0

I need to write 4 bytes from input pins to different parts of a register depending on a counter, with the code i have now I get this error:
Error (10734): Verilog HDL error at m.v(156): cnt is not a constant
How should I deal with it?

wire wren, rst;     
wire [3:0] abcd;    
reg [31:0] my_reg;    
reg [3:0] cnt;   


always @(posedge wren or posedge rst)   
begin   
   if (rst == 1) 
   begin 
      my_reg <= 0; 
   end    
   else 
   begin   
      if (wren == 1) 
      begin    
         my_reg [4*cnt+3:4*cnt] <= abcd;   
      end   
   end          
end  
Roman Kishmar
  • 37
  • 1
  • 2
  • 11

1 Answers1

2

As for your error: you should use the +: syntax [4*cnt +: 4] See here for more information.

Even if that would be semantically allowed your values would be wrong:

  • [4*cnt-1:4*cnt] would give a low:high index e.g. if cnt=1 you get [3:4]

  • [4*cnt-1:4*cnt] gives a negative index if cnt==0 [-1:0] which is outside the range [31:0] of reg.

You probably meant to use [4*cnt+3:4*cnt]

But you have other errors too.

First it is very dangerous to use a keyword for a variable. (reg)

Second you are clocking using a non-clock signal: wren. This creates another clock tree. The normal procedure is to use an if with the standard system clock:

always @(posedge clk or posedge rst)   
begin   
   if (rst == 1) 
   begin 
      my_reg <= 0; 
   end    
   else 
   begin   
      if (wren == 1) 
      begin    
         my_reg [4*cnt +: 4] <= abcd;   
      end   
   end          
end  
Oldfart
  • 6,104
  • 2
  • 13
  • 15
  • I did mean "[4*cnt+3:4*cnt]" thanks. about "reg"s: sorry, I shortened some of the names for better readability, it's actually not reg, ofcourse )) – Roman Kishmar Feb 07 '19 at 08:43
  • what is so dangerous about creating another clock tree ? – Roman Kishmar Feb 07 '19 at 08:56
  • 'my_reg [4*cnt +: 4]' is this correct ? it looks like there's an eror here (to me) – Roman Kishmar Feb 07 '19 at 08:58
  • 1
    this is correct. it means that the width of the range is `4` and it would be equivalent to `[4*cnt + 3: 4*cnt]` if verilog could compile the latter. – Serge Feb 07 '19 at 11:54
  • @RKishmar: You can do this type of bit slicing in VHDL (e.g., `my_reg(4*cnt+3 downto 4*cnt)`), but only with literals in Verilog (e.g., `my_reg[3:0]` and `my_reg[7:4]`). There is no good reason why, it's just a limitation in the language. Verilog has the `+:` operator instead. – pc3e Feb 07 '19 at 22:22
  • @pc3e I know that, but I want to get some practice in verilog :) – Roman Kishmar Feb 08 '19 at 04:29