Один вход в массив пользовательских модулей в Verilog

StackOverflow https://stackoverflow.com/questions/1651637

  •  22-07-2019
  •  | 
  •  

Вопрос

Итак, у меня есть массив из 4 модулей ОЗУ, которые я хочу иметь возможность чтения / записи на основе двух разных сигналов селектора. Прямо сейчас я создаю экземпляр ОЗУ с помощью промежуточных сигналов:

    genvar i;
    generate
    for (i = 0; i < regnum; i=i+1) begin: regs    
         rfram_generic rf (clk,rst,ce_a_int[i],addr_a_int[i],do_a_int[i],
                               ce_b_int[i],addr_b_int[i],do_b_int[i],
                               ce_w_int[i],we_w_int[i],addr_w_int[i],
                               di_w_int[i]);
    end
    endgenerate

И я хочу выбрать ОЗУ для использования с использованием сигналов head или tail (2-битные векторы). Есть идеи, как это сделать?

Это было полезно?

Решение

Я здесь новичок и пока не могу комментировать вопросы, но в ответ на Марти: большинство инструментов синтеза ПЛИС преобразуют внутренние многоисточниковые сигналы с тремя значениями в MUX-подобную логику, где это возможно. См., Например: описание старого поведения тристата в логике, которое звучит точно для меня .

Как рекомендация Адаму, вам, вероятно, лучше сделать это явным в своем коде, выполнив маскировку самостоятельно, а не используя тристаты. Это улучшит переносимость, даст вам более предсказуемые результаты и послужит самодокументированием, если кто-нибудь когда-нибудь будет пересматривать ваш код.

Тем не менее, делая некоторые предположения на основе вашего решения, возможно, имеет смысл просто замаскировать включение синхронизации на порте записи и преобразовать выходной сигнал порта чтения. Например:

reg [WIDTH-1:0] do_a,do_b;
always @(*) do_a = do_a_int[head];
always @(*) do_b = do_b_int[tail];
generate
   genvar i;
   for (i = 0; i < regnum; i=i+1) begin: regs    
      rfram_generic rf (clk,rst,
                        ce_a,addr_a,do_a_int[i],
                        ce_b,addr_b,do_b_int[i],
                        ce_w,head==i?we_w:1'b0,addr_w,di_w);
   end
endgenerate

Это, вероятно, приведет к менее сложной логике (, т.е. , лучшей области и задержке), чем ваше решение.

Другие советы

Я думаю, я понял это, должен использовать оператор создания:

genvar i;
generate 
    for (i = 0; i < regnum; i=i+1) begin: sigassign
        //read from the checkpoint in progress
        assign ce_a_int[i] = (head == i) ? ce_a : 'bz;
        assign addr_a_int[i] = (head == i) ? addr_a : 'bz;
        assign do_a = (head == i) ? do_a_int[i] : 'bz;
        //write to the checkpoint in progress
        assign ce_w_int[i] = (head == i) ? ce_w : 'bz;
        assign we_w_int[i] = (head == i) ? we_w : 'bz;
        assign addr_w_int[i] = (head == i) ? addr_w : 'bz;
        assign di_w_int[i] = (head == i) ? di_w : 'bz;
        //read from the last stable checkpoint
        assign ce_b_int[i] = (tail == i) ? ce_b : 'bz;
        assign addr_b_int[i] = (tail == i) ? addr_b : 'bz;
        assign do_b = (tail == i) ? do_b_int[i] : 'bz;
    end
endgenerate

рад слышать, что вы нашли решение вашей проблемы. Должен признать, что я не совсем понял, что вы задумали, но в одном комментарии вы также можете использовать if внутри генерации операторов и, таким образом, создавать экземпляры различных модулей или использовать разные сигналы в зависимости от genvar , например:

generate
    genvar i;
    for (i = 0; i < regnum; i=i+1) begin: regs
        if (i == head) begin
            rfram_generic_a rf(...);
        end else if (i == tail) begin
            rfram_generic_b rf(...);
        end else begin
            rfram_generic_c rf(...);
        end
    end
endgenerate
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top