Search code examples
for-loopswitch-statementverilogsynthesis

Big multiplexer with for loop in Verilog


I want my circuit to write a value between 010 and 25510 to a reg called mem_address_reg depending on an incoming address. After an and-operation this address can take one of 25610 different values. I want the circuit to be combinational, so one way to check the value is to build a multiplexer with 25610 different inputs that then writes one of those to the output, depending on the incoming address (the select line of the multiplexer).

This circuit works but requires me to write a script that generates all 25610 case-statements and the code gets bloated. So instead of writing each and every line myself I want to use a for loop that generates those for me. Unfortunately this doesn't seem to work.

What did I do wrong?

The working circuit with bloated code:

wire [31:0] masked_write_adr;
reg  [29:0] nvmm_write_request_adr;
reg  [7:0]  mem_address_reg;     

assign masked_write_adr = {2'b00, nvmm_write_request_adr} & 32'hFFC0_0000;

always@(*)
begin
    case(masked_write_adr)
      32'h0000_0000:  mem_address_reg = 8'h00;
      32'h0040_0000:  mem_address_reg = 8'h01;
      32'h0080_0000:  mem_address_reg = 8'h02;
      32'h00C0_0000:  mem_address_reg = 8'h03;
      32'h0100_0000:  mem_address_reg = 8'h04;
      32'h0140_0000:  mem_address_reg = 8'h05;
      (...)
      32'h3FC0_0000:  mem_address_reg = 8'hFF;
      default:        mem_address_reg = 8'h0;
    endcase
end

This is what I thought to be an analog circuit which does not work:

wire [31:0] masked_write_adr;
reg  [29:0] nvmm_write_request_adr;
reg  [7:0]  mem_address_reg;     

assign masked_write_adr = {2'b00, nvmm_write_request_adr} & 32'hFFC0_0000;

integer k;
always@(*)
begin
  mem_address_reg <= 8'h00;
  for(k=0; k<255; k=k+1)
  begin
      if((k*32'h40_0000) == masked_write_adr)
        mem_address_reg <= k;
  end              
end

Solution

  • just do

    assign mem_address_reg = masked_write_addr[29:22];