I come from very predominant background in VHDL and have recently been doing a lot more coding in SystemVerilog. I've noticed a couple of strange behaviours that I don't entirely understand.
Summary
In the following example, I am performing an addition of several signals. I know that this is particularly inefficient (and probably bad style), but I am using it to demonstrate the type of issue I've run into recently.
// Main add (inside synchronous process)
// all signals are 32b logic or reg (except for 64, which is a `define)
dma_ins.dest <= sdram_addr + slice_address + slice_offset - 64;
0x3800 0000 0x0001 0000 0x0000 0050
When I run this add in simulation, I get the correct result. In synthesis, it's incorrect.
Simulation: 0x38010010
Synthesis: 0x38008008
The synthesis value is one shift to the right (0x8008 instead of 0x10010).
In order to determine the synthesis value, I am writing all four signals to debug registers. The DMA also ends up at the wrong address in the SDRAM in hardware.
In order to fix this issue, I did the following:
dma_ins.dest <= sdram_addr;
dma_ins.dest[26:15] <= queue_prop_new[0].contig_head; // non-shifted versions of slice address
dma_ins.dest[14:4] <= queue_prop_new[0].contig_hoffset - 4; // and slice offset
I'm probably missing something in regards to the SystemVerilog type definitions, but I'm not sure what. I've added some details below.
Detail
The signals being added together are defined as follows:
// SDRAM ADDR (synchronus process, 32b reg)
sdram_addr <= 32'h38000000
// SLICE ADDRESS (asynchronus combinitorial assign)
// slice address: 32b logic
// queue_prop_new[0].contig_head: 12b logic: value of 0x02
// 32768 is a `define that has been substituted.
assign slice_address = (queue_prop_new[0].contig_head <<($clog2(32768)-1));
// (slice_address = 0x02 << 15 = 0x10000)
// SLICE OFFSET
// slice_offset: 32b logic
// queue_prop_new[0].contig_hoffset: 11b logic: value of 0x05
// 16 is a substituted `define
assign slice_offset = (queue_prop_new[0].contig_hoffset<<($clog2(16)-1));
// (slice_offset = 0x05 << 4 = 0x50)
-
\$\begingroup\$ As I've been writing this, I've actually got a hunch as to what the reason is: adding two 32-bit numbers produces a 33-bit number and my simulator is crap. \$\endgroup\$stanri– stanri2015年07月17日 18:28:11 +00:00Commented Jul 17, 2015 at 18:28
-
\$\begingroup\$ If the addition overflows but then the subtraction corrects this, underflowing, bringing it back in range you have the potential to be ok. I would try with 31 bit values and see if you still see the issue. the simulator might be struggling with values greater than 32 bits (not overflow/underflowing correctly. \$\endgroup\$pre_randomize– pre_randomize2015年07月17日 19:16:04 +00:00Commented Jul 17, 2015 at 19:16
-
\$\begingroup\$ No, it has nothing to do with 32 bits width. Obviously, with the numbers given in your example, nothing is overflowing. Besides, the simulation is correct and the synthesis is wrong, so it has nothing to do with your simulator, either. \$\endgroup\$Dave Tweed– Dave Tweed2015年07月17日 19:24:56 +00:00Commented Jul 17, 2015 at 19:24
1 Answer 1
The expressions ($clog2(32768)-1)
and ($clog2(16)-1)
look suspicious to me — don't they yield 14 and 3, respectively, rather than the 15 and 4 that you desire?
But I can't explain why the simulator is getting the "correct" result.
-
\$\begingroup\$ the $clog2 is not the same as log2. the $clog2(n) produces the number of bits necessary to store the value n. As a result, $clog2(16) = 5. I subtract 1 to get 4, the actual log2 value. Additionally, I have looked up the intermediate signals (slice_) in hw and they produce the correct values (with the right shifts). \$\endgroup\$stanri– stanri2015年07月17日 19:35:53 +00:00Commented Jul 17, 2015 at 19:35
-
\$\begingroup\$ No, it doesn't.
clog2()
is an abbreviation for "ceiling (log2 ())", and it yields the number of address bits required to address a memory of the given size, not the number of bits required to represent the size itself. When the argument is a power of 2, log2 and clog2 give the same result. \$\endgroup\$Dave Tweed– Dave Tweed2015年07月17日 19:40:58 +00:00Commented Jul 17, 2015 at 19:40 -
\$\begingroup\$ Huh, you're right. I must have misunderstood. I assumed my understanding was correct because that's what the simulation tool produced. \$\endgroup\$stanri– stanri2015年07月17日 19:48:34 +00:00Commented Jul 17, 2015 at 19:48