|
From: Martin W. <mai...@ma...> - 2016-11-09 09:06:22
|
Niels Möller wrote: > Hi, > > here's a case where I'm not sure if I'm confused, or if iverilog is... > Consider the following input (it could easily be simplified to avoid the > problem, but it exhibits a problem present in my real, more complicated, > code, which uses generate to produce code where each instance assigns to > one piece of a variable): > > module with_assign (input [3:0] in, output [1:0] out); > assign out[0] = in[0] ^ in[2]; > assign out[1] = in[1] ^ in[3]; > endmodule > > // Note must use "reg" output, or assignments are invalid. > module with_always (input [3:0] in, output reg [1:0] out); > always @(*) > out[0] = in[0] ^ in[2]; > always @(*) > out[1] = in[1] ^ in[3]; > endmodule > > Until yesterday, I thought these were equivalent. The code passes > iverilog -Wall without complaints. But when I try synthesize using > iverilog -t sizer, the second module fails, with errors and warnings: > > test.vl:10: warning: A latch has been inferred for some bits of 'out'. > test.vl:10: sorry: Bit-level latch gate enables are not currently > supported in synthesis. > test.vl:10: error: Unable to synthesize asynchronous process. > test.vl:8: warning: A latch has been inferred for some bits of 'out'. > test.vl:8: sorry: Bit-level latch gate enables are not currently > supported in synthesis. > test.vl:8: error: Unable to synthesize asynchronous process. > 4 error(s) in post-elaboration processing. > > My interpretation of that is that if I want an always block to be > combinatorial, and I assign one bit in a variable (above, "out"), I have > to assign all bits of the variable. Is it supposed to work that way? Yes, your two pieces of code are equivalent. The problem is twofold: 1) For each 'always' process, iverilog calculates an output sensitivity list, i.e. a list of variables that are written to by that process. The granularity of this list is nets/variables, not bits. This is all that is needed for simulation, which just needs to determine the update events for the statement. 2) The synthesis option in iverilog is very primitive. It considers each 'always' process in isolation. It uses the output sensitivity list to find variables that are written to, then checks if all bits of the variable are written by all branches within the process. If not, it infers a latch. For this case, the solution is to put your two assignments in the same always statement, i.e. module with_always (input [3:0] in, output reg [1:0] out); always @(*) begin out[0] = in[0] ^ in[2]; out[1] = in[1] ^ in[3]; end endmodule Currently there are no plans to improve synthesis support in iverilog. I fix bugs when they are reported, but if it either generates correctly behaving code or tells you it can't, that's where I stop. Turning it into a useful synthesis tool would be a major piece of work, and we still have a lot to do on the simulation side. Martin |