开发者

Single Input to Array of Custom Modules in Verilog

So I have an array of 4 RAM modules that I want to be able to read/write to based on two different selector signals. Right now I'm instantiating the RAM using intermediary signals:

    genvar i;
    generate
    for (i = 0; i < regnum; i=i+1) begin:开发者_如何学Go 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

And I want to select the RAM to use using either head or tail signals (2-bit vectors). Any ideas how to do this?


I'm new here and can't comment on questions yet, but in response to Marty: most FPGA synthesis tools will translate internal multisource signals with tristate values into MUX-like logic, where possible. See, for instance: a description of old tristate-to-logic behaviour that sounds accurate to me.

As a recommendation to Adam, you're probably better off making this explicit in your code by performing the masking yourself rather than using the tristates. This will improve portability, give you more predictable results, and serve as self-documentation if anybody ever has to revisit your code.

However, making some guesses based on your solution, it would probably make sense to simply mask off the clock enable on the write port and mux the output of the read port. For instance:

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

This will probably result in less complex logic (i.e., better area and delay) than your solution.


I think I figured it out, gotta use a generate statement:

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


glad to hear you found a solution for your problem. I must admit I didn't fully understand what you were up to, but one comment, you can also use if inside generate statements and thus instantiate different modules or use different signals dependent on the genvar, e.g.:

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜