Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Bit Width using Parameters in Verilog

Status
Not open for further replies.

Ashish Agrawal

Member level 3
Joined
Mar 24, 2015
Messages
60
Helped
8
Reputation
16
Reaction score
8
Trophy points
8
Activity points
502
Hi,

I am having a memory (depth = 64, width = parameter) to be read fully and put it in a 1-D array (width = 64*memory data width). Only 1 row can be read at a time.
This is the verilog code I have written


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
parameter MEM_DATA_WIDTH = 32;
localparam DATA_WIDTH_O = 64*MEM_DATA_WIDTH;
 
reg [DATA_WIDTH_O -1 : 0] fsm_out;
wire [MEM_DATA_WIDTH -1 :0] mem_data_i;
reg [5:0] mem_addr;
 
///logic for generating mem_addr/////
//////////////////////////////////////////
 
always @ *
  begin
       if (valid_i)
         fsm_out [(mem_addr + 1)*MEM_DATA_WIDTH -1 : mem_addr *MEM_DATA_WIDTH]  <= mem_data_i;
  end




I am getting an error during compilation related to constant parameter for following operations
(mem_addr + 1)*MEM_DATA_WIDTH and mem_addr *MEM_DATA_WIDTH

Can anyone tell me how to fix this error?
Thanks in advance.
 
Last edited by a moderator:

Ashish Agrawal

Member level 3
Joined
Mar 24, 2015
Messages
60
Helped
8
Reputation
16
Reaction score
8
Trophy points
8
Activity points
502
Can anyone help me how to fix this error if it is because of inappropriate syntax?
And if it is not just a syntax error then what should I do to get that functionality in my design?

Thanks in advance.
 

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,805
Helped
1,809
Reputation
3,628
Reaction score
1,768
Trophy points
1,393
Location
USA
Activity points
58,912
Honestly you need to write good comments in your code.
What you want is to build a demultiplexer to select the 32-bit bit slice of the 64*32-bit wide fsm_out and load your 32-bit data into it.


Code Verilog - [expand]
1
2
3
4
5
6
7
// part selects take the form:
// [lower_starting_index +: width_of_slice] or
// [upper_starting_index -: width_of_slice]
// therefore....
 
fsm_out [mem_addr*MEM_DATA_WIDTH-1 +:32] = mem_data_i; // blocking assignment as this 
                                                       // is a combinational always block

 

Ashish Agrawal

Member level 3
Joined
Mar 24, 2015
Messages
60
Helped
8
Reputation
16
Reaction score
8
Trophy points
8
Activity points
502
Hi ads-ee,

Your understanding is right. But the error still exists with the following operation
mem_addr*MEM_DATA_WIDTH
As MEM_DATA_WIDTH is a constant (parameter) while mem_addr is a variable (reg).
 

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,805
Helped
1,809
Reputation
3,628
Reaction score
1,768
Trophy points
1,393
Location
USA
Activity points
58,912
I just tried the following testcase using Vivado's simulator.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module demux #(
  parameter MEM_DATA_WIDTH = 32,
  parameter DATA_WIDTH_0 = 64*MEM_DATA_WIDTH
) (
  output reg [DATA_WIDTH_0-1:0] fsm_out,
  input [MEM_DATA_WIDTH-1:0] mem_data_i,
  input [5:0] mem_addr_i,
  input clk
);
 
reg [5:0] mem_addr;
always @ (posedge clk) mem_addr <= mem_addr_i;
 
always @* begin
  fsm_out [mem_addr*MEM_DATA_WIDTH +:MEM_DATA_WIDTH] = mem_data_i;
end
endmodule


and it compiles with no errors.

What simulator (and version) are you using? I know all recent Modelsim versions support it.

You might have to resort to an ugly case statement if your simulator can't support code like above:

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
always @* begin
  case (mem_addr)
    0     : fsm_out [ 0*MEM_DATA_WIDTH +:MEM_DATA_WIDTH] = mem_data_i;
    1     : fsm_out [ 1*MEM_DATA_WIDTH +:MEM_DATA_WIDTH] = mem_data_i;
    2     : fsm_out [ 2*MEM_DATA_WIDTH +:MEM_DATA_WIDTH] = mem_data_i;
    // ...
    61    : fsm_out [61*MEM_DATA_WIDTH +:MEM_DATA_WIDTH] = mem_data_i;
    62    : fsm_out [62*MEM_DATA_WIDTH +:MEM_DATA_WIDTH] = mem_data_i;
    63    : fsm_out [63*MEM_DATA_WIDTH +:MEM_DATA_WIDTH] = mem_data_i;
  endcase
end



BTW, the -1 in the first post for the fsm_out was a typo from cutting pasting from your original post. Sorry about that.
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,272
Helped
14,226
Reputation
28,713
Reaction score
12,919
Trophy points
1,393
Location
Bochum, Germany
Activity points
279,546
But the error still exists with the following operation
mem_addr*MEM_DATA_WIDTH
Your snippet compiles correctly when changed to indexed part select.
 

Ashish Agrawal

Member level 3
Joined
Mar 24, 2015
Messages
60
Helped
8
Reputation
16
Reaction score
8
Trophy points
8
Activity points
502
What simulator (and version) are you using? I know all recent Modelsim versions support it.
I am using cadence ncsim version 14.2
It might be a simulator problem as I also remember that Modelsim supports it.

BTW, can any work around be done instead of using ugly Case statement ?
I don't want to use case statement because in future mem_addr can be 10 bit also (memory depth may change), so writing 1024 case items isn't a good idea.
 

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,805
Helped
1,809
Reputation
3,628
Reaction score
1,768
Trophy points
1,393
Location
USA
Activity points
58,912
You can check the documentation for ncsim and see if it defaults to '95 support only and you need to enable 2001 support. I'd be very surprised if it really doesn't support the part select syntax.

This code also requires Verilog 2001 support.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
integer i;
always @* begin
  for (i=0;i<64;i=i+1) begin
    if (mem_addr == i) begin
      fsm_out [i*MEM_DATA_WIDTH +: MEM_DATA_WIDTH] = mem_data_i;
    end
  end
end


The for loop should unroll into identical code with the other versions.

You talk about this being memory, but this code probably doesn't synthesize to a memory. It doesn't conform to any standard inferred memory template. The standard templates use an array.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top