Verilog counter counts wrong - counter

I'm trying to implement a counter that counts up an internal value every clock-pulse with an input value.
module Counter(in, clk, out);
input clk;
input [7:0] in;
wire clk;
wire [7:0] in;
output [7:0] out;
reg [7:0] out;
always # (posedge clk) begin
out <= out + in;
end
endmodule
The output I get is correct most of the time but sometimes the counter does not increment as expected. Here is a link to a waveform of the output. As can be seen the counter jumps from 5 to 10 even though in is 3. Can someone help me?

Your output appears to be in octal in the waveform, or base 8 (I'm guessing this is the 'O 000' in the second column).
In this case 'd5 + 'd3 = 'd8 ('o010). So everything seems to be working correctly.

Related

How does always_ff works?

I do have a problem understanding how always_ff works in a way of creating a mesh of logic gates.
What do I mean ? When I use always_comb like here :
module gray_koder_dekoder(i_data, i_oper, o_code);
parameter LEN = 4;
input logic [LEN-1:0] i_data;
input logic i_oper;
output logic [LEN-1:0] o_code;
int i;
always_comb
begin
o_code = '0;
i = LEN-1;
if (i_oper == 1'b1) // 1'b1 - operacja
begin // kodowania
o_code = i_data ^ (i_data >> 1);
end
else // dla kazdej innej wartosci
begin // realizuj dokodowanie
o_code = i_data;
for (i=LEN-1; i>0; i=i-1)
begin
o_code[i-1] = o_code[i]
^ i_data[i-1];
end
end
end
endmodule
So how do I see it.
At the beggining the program sees that output is 0000,
now if the i_oper is equal 1 so the input is 1 then it checks changes the o_code to i_data ^ (i_data >> 1) so now the program want's to do combination of logic gates for this operation but if the i_oper is equal 0 then the program makes another set of logic gates to get different o_code.
So the always_comb gives the final result for every bite in the i_data that results in o_code.
So my teacher said that always_comb is "blocking" but always_ff is not "blocking" I don't get it ...
So the always_ff doesn't give the final result of logic gates for the input to get a specific output ?
Another example of always_comb :
module gray_dekoder (i_gray, o_data);
parameter LEN = 4;
input logic [LEN-1:0] i_gray;
output logic [LEN-1:0] o_data;
always_comb
begin
o_data = i_gray;
for (int i=LEN-1; i>0; i=i-1)
o_data[i-1] = o_data[i] ^ i_gray[i-1];
end
endmodule
So at the beggining the program sees that the output is 0000 so it will make a set of logic combination to have 0 at the end. Then he sees loop for that modifies the output so the program checks every bit of the input like bit nr 3 then nr 2 then nr 1 etc. and creates for every input specific output so now the output is not 0000 anymore but set of instructions that modifies the output made from loop "for"
so the always comb gives a final result from the analizing the whole code from top to bottom of "always_comb" and creates a set of instructions/set of logic gates that helps it. Because always_comb overwrites the previous instructions like 0000 it was a basic instruction but then was overwrited by the loop "for"
But maybe I think wrongly because if instruction doesn't overwrite the 0000 instruction like here :
module replace(i_a, i_b, o_replaced, o_error);
parameter BITS = 4;
input logic signed [BITS-1:0] i_a, i_b;
output logic signed [BITS-1:0] o_replaced;
output logic o_error;
int i;
always_comb
begin
o_replaced = '0;
if(i_b < 0 || i_b > BITS)
begin
o_error = 1;
o_replaced = 'x;
end
else
begin
i = i_b;
o_replaced = i_a;
o_replaced[i-1] = 1;
o_error = 0;
end
end
endmodule
I have here 0000 output that isn't overwrited for "else" So I don't know what happens then.
I think of always_comb as an "final result" that gives a set of instructions how to create logic gates. But the final result is at the end, so if something changes then the beggining result doesn't matter "overwrited" but with if loop it doesn't work with my mind set.
So always_ff I heard that it doesn't give a final result that it can stop at any point not like in always_comb that the program analysis from top to bottom.
Verilog is designed to represent behavior of hardware and it is not a regular programming language. It operates different semantics.
At a very top glance, hardware consists of combinational logic and flops (and latches). From the other point of view hardware is a set of parallel functions which are synchronized across design by clocks. This means that at a clock edge a lot of hardware devices start working in parallel and they should produce results by the next clock edge. Those results could be used by other functions at the next clock cycle.
Roughly, combinational logic defines a function, flops provide synchronization.
In verilog all those devices are described with always blocks. TUse of edges, e.g., #(posedge clk) provides synchronization points and usually defines flops in the code. A simple function and a flop look like the following.
// combinational logic
always #* // you can use always_comb instead
val = in1 & in2; // a combinational function
// flop
always #(posedge clk) // you can use always_ff instead
out <= val; // synchronization
So, in the example val is calculated by the combinational function and its synchronous out is made available to other functions to be used by a flop. You can see progression of clocks and results in a waveform.
So, this is what always_ff is doing, just providing synchronization and expressing flops for synthesis.
In general, always, always_comb, always_ff and always_latch are identical. The last three are system verilog blocks and just provide additional hints to the compiler which can run additional checks on them. I intentionally used just always blocks in my example to show that. There are some other conditions which need to be programmed to cleanly express the intention. So, your assertion about different working of always_ff has no base. It works the same as other always blocks.
What I think confuses you, is use of blocking (=) and non-blocking (<=) assignments. It does not matter for synthesis which one you use, but it matters for simulation. The difference is described and numerous documents and examples. To understand it properly you need to look into verilog simulation scheduling semantics.
But the rule of thumb is that you should use non-blocking assignments (<=) in flops and use blocking (=) in combinational logic. In flops '<=' allows simulating real behavior of flops. Remember that hardware is a massively-parallel evaluation engine. Consider the following example:
always_ff #(posedge clk) begin
out1 <= in1;
out2 <= out1;
end
The above example defines at least two flops working at posedge clk. out1 and out2 must be synchronized at this clock. It means, the flops have to catch values which existed before the edge and present them after the edge. So, for out1 the value existed before the edge is in1, evaluated by a combinational logic. What would be the value of out2? Which value existed before the edge? Apparently, the value of the out1 before it gets changed to the new value of in1.
clk ___|---|___|---|___
in1 0
out1 x 0 << new value of in1
out2 x << old value of ou1
.
in1 1 .
out1 . 1 << new value of in1
out2 . 0 << old value of ou1
So, after evaluation of the block, the at the first edge the value of out2 will be 'x' (previous value of out1), at the second clock edge it will finally get value of 'in1' as it existed at the previous clock cycle.
I hope it would make your understanding a bit better.

SystemVerilog 2-bit register decoding problem

I have two 2-bit inputs and an output of 1-bit. So what I'm trying to do is code a next state value with taking AND of the two inputs, then use non-blocking <= to assign that value into register xy_r, which is now two D-flipflops. So I am seeking to get always the XOR-value of the xy_r previous clock edge as my output xor_out. I suppose that the way below is not the right one?
It worked in the simulation but then again in RTL Synthesis I didn't end up with an XOR gate but a third flip-flop so it seems like xor_out is treated as a register.
I suppose I can't use assign outside of the if-else-statements because in that case the output wouldn't follow the xy_r previous state but the present.
Can you please assist me how to solve this issue, if there is a somewhat simple way.
module 2ffsxor
(input logic clk,
input logic rst_n,
input logic [1:0] x_in,
input logic [1:0] y_in,
output logic xor_out
);
logic [1:0] xy;
logic [1:0] xy_r;
always # (posedge clk or negedge rst_n)
begin
if (rst_n == '0)
xy_r <= '0;
else
begin
xy = x_in & y_in;
xy_r <= xy;
xor_out = xy_r[0] ^ xy_r[1];
end
end
endmodule
And here's a schematic what it should be:
Schematic 2ffsxor
Synthesis treats this code as if you had wrote
begin
xy_r <= x_in & y_in;
xor_out <= xy_r[0] ^ xy_r[1];
end
That's two stages of registers. But since you assigned xor_out with a blocking assignment, you have a simulation race condition for any process that tries to read xor_out. The race would be from the result from the previous values of xy_r and the result before that!
If you use an continuous assign statement outside this always block, any process reading xor_out on the clock edge will see the result from the previous state of xy_r.
But why not write this as on register:
always # (posedge clk or negedge rst_n)
begin
if (rst_n == '0)
xor_out <= '0;
else
begin
xy = x_in & y_in;
xor_out <= xy[0] ^ xy[1];
end
end

Bus in sensitivity list in SystemVerilog

Is it possible to evaluate statements in an always block when any bit in a bus is toggled(posedge)? e.g. If I have:
input [1:0] a;
always#([what to do here?]) begin
[statements]
end
I have tried
always#(posedge a)
and also
always#(posedge a[1:0])
but simulation shows only on posedge of a[0] are the statements evaluated.
I am not able to use "," or "or" because the width is determined by a parameter.
Thank you in advance!
You need to generate a process for each bit
event ev;
for (genvar ii =0;ii<$bits(a);ii++) begin
always #(posedge a[ii] ) ->>ev;
end
always #ev ...

LFSR description right?

I wrote a 32-bit LFSR based on the taps from [1]. I want to ask if the following description is right for the 32-bit LFSR with the taps 32,22,2 and 1.
module lfsr (
input logic clk_i,
input logic rst_i,
output logic [31:0] rand_o
);
logic[31:0] lfsr_value;
assign rand_o = lfsr_value;
always_ff #(posedge clk_i, negedge rst_i) begin
if(~rst_i) begin
lfsr_value <= '0;
end else begin
lfsr_value[31:1] <= lfsr_value[30:0];
lfsr_value[0] <= ~(lfsr_value[31] ^ lfsr_value[21] ^ lfsr_value[1] ^ lfsr_value[0]);
end
end
endmodule
[1] http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
Looks Ok. you could also use an XOR, instead of an XNOR, as long as you reset to something else (the XOR version locks up at all 0's, the XNOR at all 1's).
For many apps the pseudo-random output is the single bit you shift out (31 in your case), rather than the entire register. It's also (more?) common to shift right, and put the XOR data in the top bit, and use the bit 0 output as your PR data.
Your code is specifically SystemVerilog, and not Verilog, so I've removed the Verilog tag.

assign statement for RTL readability in an interface causes assignments or a buffer in synthesis

We have an interface with modports connectin gmodules that looks something like this:
interface test_interface (clk, in1, out1);
input logic in1;
output logic out1;
input logic clk;
logic mid1;
logic aliased_signal;
modport a_to_b (
input in1,
input clk,
output mid1,
input aliased_signal
);
modport b_to_a (
input clk,
input mid1,
output out1,
output aliased_signal
);
endinterface : test_interface
module top(clock, inpad, outpad);
input logic clock;
input logic inpad;
output logic outpad;
test_interface test_if(.clk(clock), .in1(inpad), .out1(outpad));
a A0(.a2b(test_if));
b B0(.b2a(test_if));
endmodule
module a ( test_interface.a_to_b a2b);
always_ff #(posedge a2b.clk) begin
a2b.mid1 <= a2b.in1 & a2b.aliased_signal;
end
endmodule
module b (test_interface.b_to_a b2a);
assign b2a.aliased_signal = b2a.out1;
always_ff #(posedge b2a.clk) begin
b2a.out1 <= ~b2a.mid1;
end
endmodule
This is a trivial example, but demonstrates the problem. In the real design, we have, for example 32-bit outputs and 8 bits of that may go to one place and 8 bits to another, etc. In the destination, they would like to use names that are more meaningful in the destination module, so are using assignments to create those names in the interface so that the destination code isn't using just part of the bits of an obfuscated bus name in the interface.
While the above simulates fine, the result is assignment statements during synthesis (even if using always_comb obviously) and while we can have the synthesis tool insert buffers to make APR happy, this is not desired when these signals are just used as convenient aliases basically.
Is there an RTL coding style with SV interfaces that would allow such "aliasing" without creating complications downstream in synthesis/APR tools?
Below is a closer example to what I'm trying to do. The "obfuscated_name" signal is an output of the a module because some modules use the name directly from the interface (this could be cleaned up to only do what the a->b connection is doing), but I get the same errors from IUS and DC if I connect to mid2 a->c instead of using the obfuscated_name signal directly.
interface test_interface(clk, in1, out1, out2);
input logic [7:0] in1;
output logic [3:0] out1;
output logic [3:0] out2;
input logic clk;
logic [7:0] obfuscated_name;
logic [3:0] mid1;
logic [3:0] mid2;
modport a_mp (
input clk,
input in1,
output obfuscated_name
);
modport a_to_b (
input clk,
input .mid1(obfuscated_name[3:0]),
output out1
);
modport a_to_c (
input clk,
input obfuscated_name,
output out2
);
endinterface : test_interface
module a ( test_interface.a_mp a_intf);
always_ff #(posedge a_intf.clk) begin
a_intf.obfuscated_name <= ~a_intf.in1;
end
endmodule
module b (test_interface.a_to_b b_intf);
always_ff #(posedge b_intf.clk) begin
b_intf.out1 <= b_intf.mid1;
end
endmodule
module c (test_interface.a_to_c c_intf);
always_ff #(posedge c_intf.clk) begin
c_intf.out2 <= ~c_intf.obfuscated_name[7:4];
end
endmodule
module top( input logic clock,
input logic [7:0] inpad,
output logic [3:0] outpad1,
output logic [3:0] outpad2 );
test_interface test_if(.clk(clock), .in1(inpad), .out1(outpad1), .out2(outpad2));
a A0(.a_intf(test_if));
b B0(.b_intf(test_if));
c C0(.c_intf(test_if));
endmodule
The error I get from IUS is:
ncvlog: *E,MODPXE (test_interface.sv,18|18): Unsupported modport
expression for port identifier 'mid1'.
and DC gives this error:
Error: ./b.sv:1: The construct 'b_intf.mid1 (modport expression without a modport from parent)' is not supported in synthesis. (VER-700)
I'm hoping I'm doing something ignorant here and that this is possible what I'm trying to do.
There is a feature in Verilog called a port expression .name_of_port(expression_to_be_connected_to_port) that most people recognize in a module instance port list that they don't realize can also be used in the module deceleration port list header. This declares the name of the port, and the expression that gets connected to the port. This way a smaller part select of a larger internal bus can be made into a port.
module DUT(input clk, inout .data(bus[7:0]) );
wire [31:0] bus;
endmodule
module top;
reg clock;
wire [7:0] mydata;
DUT d1(.data(mydata), .clk(clock) );
endmodule
In SystemVerilog you can do the same thing with a modport expression.
interface test_interface (clk, in1, out1);
input logic in1;
output logic out1;
input logic clk;
logic mid1;
logic aliased_signal;
modport a_to_b (
input in1,
input clk,
output mid1,
input .aliased_signal(out1) // modport expression
);
modport b_to_a (
input clk,
input mid1,
output out1
);
endinterface : test_interface
module top( input logic clock,
input logic inpad,
output logic outpad );
test_interface test_if(.clk(clock), .in1(inpad), .out1(outpad));
a A0(.a2b(test_if));
b B0(.b2a(test_if));
endmodule
module a ( test_interface.a_to_b a2b);
always_ff #(posedge a2b.clk) begin
a2b.mid1 <= a2b.in1 & a2b.aliased_signal; // port reference to alias
end
endmodule
module b (test_interface.b_to_a b2a);
always_ff #(posedge b2a.clk) begin
b2a.out1 <= ~b2a.mid1;
end
endmodule