Перейти к содержанию
    

case с большим числом условий в verilog

Привет всем!

Возникла следующая проблема - есть сдвиговый регистр большой длины, есть управляющий сигнал, по управляющему сигналу должна выбраться часть этого большого регистра и выдаться на выход

Написал такой код

module signal_delayer_behav #(
        parameter integer MAX_DELAY_VAL = 448//in 16bit samples
    )(
    input axis_aclk,
    input axis_aresetn,
    
    (*keep = "true"*)input [15:0] delay_val,

    (*keep = "true"*)input [511:0] axis_s_tdata,
    (*keep = "true"*)input axis_s_tvalid,
    output axis_s_tready,
    (*keep = "true"*)output reg [511:0] axis_m_tdata,
    (*keep = "true"*)output reg axis_m_tvalid,
    input axis_m_tready
    );
    assign axis_s_tready = axis_m_tready;
    
    (*keep = "true"*)
    reg [MAX_DELAY_VAL*16-1 : 0] delay_tdata_shift_reg;
    (*keep = "true"*)
    reg [MAX_DELAY_VAL-1 : 0] delay_tvalid_shift_reg;
    
    (*keep = "true"*)
    wire srstn;

    xpm_cdc_async_rst #(
    
      //Common module parameters
      .DEST_SYNC_FF    (4), // integer; range: 2-10
      .RST_ACTIVE_HIGH (0)  // integer; 0=active low reset, 1=active high reset
    
    ) xpm_cdc_async_rst_inst (
    
      .src_arst  (axis_aresetn),
      .dest_clk  (axis_aclk),
      .dest_arst (srstn)
    
    );
    
    always @(posedge axis_aclk)begin
        if(!srstn)
            delay_tvalid_shift_reg <= 'b0;
        else begin
            delay_tvalid_shift_reg <= {delay_tvalid_shift_reg[MAX_DELAY_VAL-1-32 : 0], {32{axis_s_tvalid}}};
            delay_tdata_shift_reg <= {delay_tdata_shift_reg[512*(MAX_DELAY_VAL/32-1)-1 : 0], axis_s_tdata};
        end
    end
    
   integer i;
   always @(posedge axis_aclk)begin
       for (i=0; i <= MAX_DELAY_VAL-32; i=i+1)
       begin: output_delayed
        if(delay_val==i)begin
          axis_m_tdata <= delay_tdata_shift_reg[16*i+:512];
          axis_m_tvalid <= delay_tvalid_shift_reg[i];
        end
       end
   end
    
    
endmodule

Вопрос по последнему блоку always - в таком формате он не будет аналогом case и не выстроит все в параллель - так показал результат синтеза на 17.1 вивадо.

Попробовал unique но это не работает корректно когда нет else if.

Есть какие-то грамотные решения такой проблемы? Мне бы вообще последний блок сделать в асинхронке always (*), ну то есть не асинхонке а без задержки на такт. Но если сделать так то синтезатор ругнется на логикал луп,

Забыл дописать - управляющий сигнал условно константный - меняется очень редко - его изменение обрабатывается нормально

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

41 minutes ago, Lutovid said:

...

Вопрос по последнему блоку always - в таком формате он не будет аналогом case и не выстроит все в параллель - так показал результат синтеза на 17.1 вивадо.

Попробовал unique но это не работает корректно когда нет else if.

Есть какие-то грамотные решения такой проблемы? Мне бы вообще последний блок сделать в асинхронке always (*), ну то есть не асинхонке а без задержки на такт. Но если сделать так то синтезатор ругнется на логикал луп,

Забыл дописать - управляющий сигнал условно константный - меняется очень редко - его изменение обрабатывается нормально

Судя по всему вы хотите создать mux на  448 входов :shok: и шириной в 512 бит :scratch_one-s_head: и при этом входной индекс 16 бит :wacko2: и все это за такт :wacko: 

Для того можно просто написать

always_comb begin
  axis_m_tdata = '0;
  xis_m_tvalid = '0;

  if (delay_val<(MAX_VAL-31) begin
    axis_m_tdata = delay_tdata_shift_reg[delay_val*16 +:512]; // или  axis_m_tdata = delay_tdata_shift_reg >> (delay_val<<4)
    xis_m_tvalid = delay_tvalid_shift_reg[delay_val];
  end
end

и не возится с циклом - все одно получится офигенный mux какой бы параллельный case или unique не напиши :(

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, RobFPGA said:

Судя по всему вы хотите создать mux на  448 входов :shok: и шириной в 512 бит :scratch_one-s_head: и при этом входной индекс 16 бит :wacko2: и все это за такт :wacko:

Да реализация не самая удачная - при чем задача простая - на входе 32 сэмпла по 16 бит, а на выходе эти данные должны выдаться с задержкой до 448 сэмплов. В принципе есть еще 2 варианта реализации:

1) написать блоки

module signal_delayer_tmp #(
        parameter integer MAX_DELAY_VAL = 448,//in 16bit samples
        parameter integer DELAY_VAL = 0//in 16bit samples
    )(
    input [MAX_DELAY_VAL*16-1 : 0] big_shift_reg,
    input [15:0] delay_val_i;
    output [511:0] out_delayed
    );
    
    assign out_delayed = (delay_val_i==DELAY_VAL) ? big_shift_reg[DELAY_VAL*16+:512] : '0;

генерэйтом набить из 448 штук, а выходы побитово просуммировать - но возможно будет слабое место в побитовом суммировании - их там 448 проводов все же

2)вставить память с циклическими параллельными записью и чтением со смещением адреса - но этот вариант подольше писать, так что я пока его не рассматривал

Про ваш пример - я сначала так и написал, но по констрейнтам не сошлось и я решил, что возможно мне помогут директивы распараллеливания

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, Lutovid said:

..

2)вставить память с циклическими параллельными записью и чтением со смещением адреса - но этот вариант подольше писать, так что я пока его не рассматривал

Про ваш пример - я сначала так и написал, но по констрейнтам не сошлось и я решил, что возможно мне помогут директивы распараллеливания

Понятное дело не сойдется  тут как не крути директивы а у вас буде 512 штук mux  448 -> 1 - а это навскидку 6-8 слоев логики  без учета роутинга в этих зарослях -  поэтому тут только менять логику системы. Тем более задержка на памяти тут сама напрашивается раз не нужно быстро менять индекс.

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 hours ago, Lutovid said:

Да реализация не самая удачная - при чем задача простая - на входе 32 сэмпла по 16 бит, а на выходе эти данные должны выдаться с задержкой до 448 сэмплов. В принципе есть еще 2 варианта реализации:

Сдвиговый регистр на памяти. строк 10 без заголовка модуля)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 hours ago, des00 said:

Сдвиговый регистр на памяти. строк 10 без заголовка модуля)

Можно и в 1 строку набить, если без табуляции и переноса строки. Я попробовал так как мне было проще, не получилось, буду по другому)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Речь о том, что у вас громадный мультиплексор получается и ресурсов используется много, а так будет 1 блок памяти и немного обвязки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 hours ago, RobFPGA said:

Понятное дело не сойдется  тут как не крути директивы а у вас буде 512 штук mux  448 -> 1 - а это навскидку 6-8 слоев логики  без учета роутинга в этих зарослях -  поэтому тут только менять логику системы. Тем более задержка на памяти тут сама напрашивается раз не нужно быстро менять индекс.

Удачи! Rob.

Да видимо это самый удачный метод, спасибо,

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...