Обмен байтами с порядком байтов

Есть как программа для обмена порядком с прямым байтовым порядком (малым и большим), так и его тестовая среда. Поток данных поступает в модуль и преобразуется в другой порядок байтов с помощью вычислительной логики.

byte_order_swap.v

`timescale 1ns / 1ps

module byte_order_swap #
(
    parameter integer DATA_WIDTH = 32
)
(
    input wire [DATA_WIDTH - 1 : 0] data_i,
    input wire [DATA_WIDTH - 1 : 0] data_o
);
    localparam integer DATA_BYTE_NUMBER = DATA_WIDTH / 8;
    localparam integer DEC_DATA_WIDTH   = DATA_WIDTH - 1;

    generate
        genvar i;
        if (0 == (DATA_WIDTH % 4)) begin
            for(i = 0; i < DATA_BYTE_NUMBER; i = i + 1) begin
                assign data_o[(i * 8) +: 8] = data_i[(DEC_DATA_WIDTH - i * 8)  -: 8];
            end
        end
        else begin
            assign data_o = {DATA_WIDTH{1'h0}};
        end
    endgenerate

endmodule

byte_order_swap_tb.v

`timescale 1ns / 1ps

module byte_order_swap_tb;

    localparam integer              DATA_WIDTH          = 32;
    localparam integer              CLOCK_PERIOD        = 100;
    localparam integer              ITERATION_NUMBER    = 1000;
    localparam [DATA_WIDTH - 1 : 0] COUNTER_START_VALUE = 32'hAABB1122;
    
    wire [DATA_WIDTH - 1 : 0] counter_swap_value;
    
    reg                      clk;
    reg [DATA_WIDTH - 1 : 0] counter_dir_value;

    byte_order_swap #
    (
        .DATA_WIDTH (DATA_WIDTH)
    )
    byte_order_swap_dut
    (
        .data_i (counter_dir_value),
        .data_o (counter_swap_value)
    );
    
    initial begin
        clk = 1'h0;
 
        forever begin
            #( CLOCK_PERIOD / 2 ) clk = !clk;
        end 
    end
    
    initial begin
        counter_dir_value <= COUNTER_START_VALUE;
    
        repeat(ITERATION_NUMBER) begin
            @(posedge clk);
            counter_dir_value <= counter_dir_value + 1'h1;
        end
    end
    
    task check_swap;
    begin
        repeat(ITERATION_NUMBER) begin
            @(posedge clk);
            $display("A direction value:  %h -> the swap value: %h",counter_dir_value, counter_swap_value, $time);
        end
    end
    endtask
    
    initial begin
    
        check_swap;
        
        $stop();
    end

endmodule

1 ответ
1

В коде хорошо используются параметры. Однако я вижу потенциальную проблему.

    if (0 == (DATA_WIDTH % 4)) begin

Этот код, кажется, подразумевает, что поддерживается любое кратное 4. Но если я попробую DATA_WIDTH = 20, тогда я вижу z значения на выходе. Возможно, вам следует ограничить значения кратными 8:

    if (0 == (DATA_WIDTH % 8)) begin

Обычно слово «проверка» означает, что вы сравниваете фактическое значение с ожидаемым и сообщаете об ошибке, если они не совпадают. В check_swap задача просто отображает значения. Если это все, что вы хотите сделать, я предлагаю переименовать задачу как display_swap или же monitor_swap.

Однако вы можете добавить код в тестовую среду для сравнения. Если ваш набор инструментов поддерживает функции SystemVerilog, следующие дополнения / модификации обеспечат автоматическую проверку:

wire [DATA_WIDTH - 1 : 0] data_o;
generate
    if (0 == (DATA_WIDTH % 8)) begin
        assign data_o = {<< 8{counter_dir_value}};
    end else begin
        assign data_o = '0;
    end
endgenerate

task check_swap;
    repeat(ITERATION_NUMBER) begin
        @(posedge clk);
        $display("A direction value:  %h -> the swap value: %h", counter_dir_value, counter_swap_value, $time);
        if (data_o !== counter_swap_value) begin
            $display("ERROR: data miscompare", $time);
        end
    end
endtask

Для создания ожидаемых данных (data_o) Я скопировал generate код из проекта и сделал некоторые упрощения. В {<< 8{counter_dir_value}} синтаксис — еще один способ выполнить обмен байтами. См. IEEE Std 1800-2017, раздел 11.4.14. Операторы потоковой передачи (упаковка / распаковка). В '0 синтаксис — это упрощенный способ присвоения всех битов 0, эквивалентный тому, что у вас уже есть. Если вы планируете синтезировать дизайн и ваша цепочка инструментов поддерживает этот синтаксис, вы даже можете использовать этот код в своем модуле дизайна.

Небольшое примечание: с таким типом task тело, begin/end ключевые слова теперь необязательны.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *