How does adding 1'b1 to 8 bit reg work in Verilog? - verilog

I am absolute beginner in Verilog and I am wondering how does the addition statement work in this piece of program.
reg [7:0] hcount;
...
always #(posedge clk) begin
if(!n_rst) begin
hcount <= 'd0;
end else if(hcount== (WIDTH-1)) begin
hcount <= 'd0;
end else begin
hcount <= hcount + 1'b1;
end
end
I understand that 1'b1 expands to 8'b1 because hcount has 8 bit width and now the calculation will work with 8 bit now. But how exactly does that addition work? Your help is much appreciated.

Verilog is a hardware description langue in a sense that it tries to describe behavior of real hardware. One of attributes of modern hardware is clock. Clock drives flops which synchronize data across different hardware devices.
Clock behavior in verilog is simulated by posedge clk (or negede), meaning that the corresponding always block will be executed if and only if clk switches to 1 from any other value (x, z, 0);.
So, in your case, there is supposed to be a clock (clk) which gets generated somewhere in test bench. It periodically switches between 0 and 1.
As soon as it switches 0 -> 1 it gets executed. If condition is right, the hcount <= hcount + 1'b1 will be executed. As you mentioned the compiler will zero-extend 1'b1 to the 8-bit value 00000001. The rest is the same as in any programming language, hcount will be incremented.
There is certain semantic associated with the non-blocking assignment, <=, but this would be a different question. For the purpose of your question it does not matter.
So, a result will be that a single increment will be done every clock cycle unless n_rst is '0'. Also, as soon as the counter reaches WIDH - 1 it will be set to '0'. Only one operation is allowed at a single clock edge.

Related

Verilog: Always statement, trigger on positive edge for 3 bit variable

My project is to use a CPDL, which I am programming in verilog to commutate a BLDC motor. Part of that process is to read in hall sensors A,B,C.
I want to count the amount of positive edges on A,B or C. I have a 3 bit variable [2:0] hallIn to store these inputs. The code below works in a modelsim simulation but not on an actual chip. How come? What is the proper way to do this? The error message I get is: 73:12:73:55|Can't mix posedge/negedge use with plain signal references
always # (posedge hallIn[2] or hallIn[1] or hallIn[0])
Synthesize code is a subset of what Verilog will let you do. Synthesizable code requires a coding structure that can be mapped to logic cells. Non-synthesizable code is intended for behavior modeling and test benches.
Flip-flops should normally be synchronized by a common clock source; not data. With a clock, you could detect the posedge data by comparing the inputs current value against it previous value.
Example:
assign posedge_detected = |(hallIn & ~prev_hallIn);
always #(posedge clock) begin
if (reset) begin
prev_hallIn <= 3'b000;
count <= 16'h0000;
end
else begin
prev_hallIn <= hallIn;
count <= count + posedge_detected;
end
end
end

I need to generate waveform as shown. in verilog code

I need to generate a waveform, as shown in the image. But with my code, I did not get expected waveform
In the design, part got the last and valid values in a random period from test-bench.
my problem is why the I value incremented at valid not equal to one
Design code:
module design_d(clk,valid,last,data);
input clk,valid,last;
output reg [7:0] data;
reg [7:0] i;
initial
begin
data=0;
i=0;
end
always #(posedge clk,valid)
begin
if (valid)
begin
data<=i;
i=i+1;
$display("i=%d data=%d ",i,data);
end
else
begin
data <=8'bz;
end
end
endmodule
Test bench code:
module test;
reg clk,valid,last;
wire [7:0] data;
parameter clk_period=2;
design_d dut(clk,valid,last,data);
initial
begin
clk=1;
valid=1;
last=0;
end
always #(clk_period/2) clk=~clk;
always #(posedge clk)
begin
last=0;
#4 last=1;
#clk_period last=0;
#8 last=1;
#clk_period last=0;
#10 last=1;
#clk_period last=0;
#16last=1;
#clk_period last=0;
#20 last=1;
#clk_period last=0;
end
always #(posedge clk or last)
begin
valid<=1;
wait(last==1)
#clk_period;
valid<=0;
#clk_period;
valid<=1;
end
initial
begin
$dumpfile("dump.vcd");
$dumpvars(1);
#24 $finish;
end
endmodule
It seems you have difficulties with the English language, which is not your fault but because of that, I may interpret your question wrongly.
You have a waveform of what you need to achieve. This to me suggest that this is a school assignment and therefore I will treat it that way. This means I will **not* give you a complete answer but give you pointers about where you are going wrong. (This should all be in a comment but there is now way it would fit).
...got the last and valid values in a random period from test-bench.
First thing to realize is writing a test-bench is just as difficult, if not more difficult then writing the RTL code itself.
In your test-bench You are using always #(posedge clk) but inside that section you use #... statements. That by itself is not wrong. Dangerous, yes, but not necessary wrong.
But
Your clock has a time period of 2 (parameter clk_period=2;) and inside your posedge clock you use delays which are equal or bigger then the clock period. That often leads to a disaster, as you have found out.
Read up on how Verilog works, especially when the sensitivity list always #... is used: It is not triggered until all statement in the section have been dealt with. In your case it means the that it will takes several clock edges until the always block is started again.
Test Bench
I don't know what the assignment was so I'll use the waveform you have given.
As last and valid are inputs to you module I will give you pointers how to make those.
valid is high for 4 clock cycles, it is then low for one clock cycle, after which it repeats itself. This means you need a pattern which repeats itself every 5 clock cycles and thus you need to make a counter which counts 0,1,2,3,4,0,1,2,3,4,...
You should not make that using #..... statements. You should use the test bench clock and make a counter which counts!
Making a counter which counts as described above is the first thing you need to learn in HDL! You will find that you have to do that over and over and over and over .. In every piece of RTL code and every test bench.
Modulo 5 counter.
I prefer for all my modules and my test benches to have a reset.
If only that it allows me to start a new test from a known state.
reg [2:0] counter;
always #(posedge clk or negedge reset_n)
begin
if (reset_n)
counter <= ...
else // clocked section
begin
if (..)
counter <= ...
else
counter <= ...
end
end
Start fresh and get the above code running first. Observe that the counter is indeed running 0,1 2, 3, 4, 0, .. before you continue.
Derived signals .
Next learn to derive signals from that.
Basic rule: in a clocked section, if you need a signal at counter value X you have to generate that at cycle X-1.
Thus to make last high when the counter is 3 you have to set that up when the counter is 2:
always #(posedge clk...
...
if (counter==3'h2)
last <= 1'b1;
else
last <= 1'b0;
I leave making the valid to you.
Once you got your test bench running start working on your design_d module.
Some tips:
Use always non-blocking assignments <= in your clocked section. **
Do NOT use a clock period of 2, use 100 or 1000. You will find out in due time why that is better.
Do not use always #(posedge clk or [one or more signals] ) unless as per my example. **
Take care of your indenting. I had to do some mayor editing on your code.
**Sorry I can't go into details why that is good practice most of the time as that would triple the size of this answer. For now please follow the tips.
I could have written the actual code in a tenth of the time it took me to write all that so I hope you will not delete the question as others may profit from it.

Synthesis of two simulation identical designs - with and without second if in process for SET clk

I have got two identical (by means of simulation) flip flop process in verilog.
First is just a standard description of register with asynchronous reset (CLR) and clock (SET) with data in tied to 1:
always #(posedge SET, posedge CLR)
if (CLR)
Q <= 0;
else
Q <= 1;
second one is the same as above but with second if condition for SET signal:
always #(posedge SET, posedge CLR)
if (CLR)
Q <= 0;
else if (SET)
Q <= 1;
There is no differences between these two implementations of flip-flop in simulation. But what does the verilog standard says about this cases? Should these tests be equivalent as well as their netlists after synthesis process?
The "if (SET)" in your second example is redundant and would be optimized away n synthesis. Since the always block will only be entered on a posedge of SET or CLR, the else statement implies that a posedge of SET has occurred.
Incidentally, the first example is a much more accepted version for coding flip flops. I've yet to see the second version make it into a shipping design.

How to handle data going from a clock domain to another clock domain whose clock is divide by 2 version of the first clock?

I have the following code.
module tb;
reg clk;
reg clk_2;
reg [15:0] from_flop;
reg [15:0] to_flop;
initial begin
clk = 0;
clk_2 = 0;
from_flop = 1;
end
always #10 clk = ~clk;
always #(posedge clk) begin
clk_2 <= ~clk_2;
end
always #(posedge clk) begin
from_flop <= from_flop + 1;
end
always #(posedge clk_2) begin
to_flop <= from_flop;
end
endmodule
However, at time instant 10ns, from_flop and to_flop both get value = 2. This is contrary to what I was expecting. I was expecting from_flop to change from 1 to 2 at 10ns, and to_flop to change from x to 1 at 10ns.
Why is this happening and how to code such that this doesn't happen?
Usually assignments in a sequential block are use non-blocking (<=) assignments. The one notable except is for generating derived clocks, which should use blocking (=) assignments. Blocking assignments in sequential blocks are legal; but you need to know what you are doing or you will get a functional mismatch between RTL simulation and circuit. That said, you still needed to error on the side of caution when using this approach.
A flip-flop has has a clock to Q delay, there for any derived clocks will have a phase offset from its parent clock. Some synthesizing tools may compensate the offset for you, however you will need to specify all cases where this should happen to the synthesizer; it will not figure it out for you. This means you should not create derived clocks sporadically across the design. All derived clocking signals need to be generated from one dedicated module; this keeps it manageable.
In most cases you should not create any derived clock. Instead, sample every other clock by adding an extra flip-flop.
always #(posedge clk) begin
from_flop <= from_flop + 1;
if (transfer_n==1'b0) begin
to_flop <= from_flop;
end
transfer_n <= ~transfer_n;
end
This strategy keeps the design in one clock domain which usually makes synthesis easier with better timing. The area impact from the extra flop in minimal can easily be less then the area penalty from the added buffers needed to keep the derived clocks aligned.
The problem is this line:
clk_2 <= ~clk_2;
You are using a non-blocking assignment, when perhaps you wanted a blocking assignment:
clk_2 = ~clk_2;
Non-blocking assignments are scheduled after blocking assignments, so the always #(posedge clk) begin will always be clocked before always #(posedge clk_2) begin.
Obviously, this isn't synthesisable code. So, this is a simulation (scheduling) issue. If you are going to synthesise something with this functionality, consider very carefully how you generate the divided clock.
http://www.edaplayground.com/x/AyQ

7 Segment Display multiple conditions verilog

I know the question sounds strange and vague, but I got a problem getting around the Verilog.
I got a FSM which has to use a 4 7 segment displays, at one state it should show only one number on one display, at other it should use all 4 displays to display a string.
My question is how can I actually get around the always# blocks with this kind of problem.
I've tried setting in one always# two different cases in a If else block, but it didn't work out. Tried also making two modules one for the number and the other for the string, assigning different output ports but the thing is that it has to point to the same hardware ports, and it fails on the bitstream.
Could someone of you give me some tips?
Ok, I will post some code, but the main picture is that I have a master state machine and then I got another state machine. Depending on the state of the other FSM I output state number on the display. But in a different state of the master state machine I have to display a message on the 4 7segment displays. What I got now is:
Here I used CLK in order to make the message
always#(BIN_IN or CLK) begin
if(FAIL==1) begin
case(state)
left:
begin
HEX_OUT [6:0] <= F;
SEG_SELECT_OUT <= 4'b0111;
state <= midleft;
end
midleft:
begin
HEX_OUT [6:0] <= A;
SEG_SELECT_OUT <= 4'b1011;
state <= midright;
end
//same for the rest
end
else begin
case (BIN_IN)
4'h0 : begin
HEX_OUT [6:0] <= 7'b1000000;
SEG_SELECT_OUT <= 4'b0111;
end
//same logic for the other cases
Board used is Xilinx Basys 3 using vivado synthesising tool
Thanks
As Greg said:
always#(BIN_IN or CLK)
Infers combinational logic. An FSM cannot be created with combinational logic alone. As you know, a FSM needs to be able to store the state between each clock.
always#(posedge CLK)
Infers flipflops into your design. That is, the operations you do inside this always loop will be stored until the next positive edge. If you put all of the design inside this always block you will end up with a typical moore-machine where your outputs will only update on every positive clock edge.
It is a bit hard to understand what you are trying to create from your code-snippet. You are talking about two FSM's, but it seems to me that you are trying to do one combinational operation and one clocked operation. If you want your design to update some outputs - like BIN_IN - combinationally(that is, immediately) you have to do these assignments outside of the always#(posedge CLK) block. Use a always#(posedge CLK) block to update your FSM-values and then use a combinational always#(BIN_IN or FAIL) block to infer a multiplexer that will choose between your FSM-output and other outputs. Something like this might work:
always#(posedge CLK)
begin
case(state)
left:
begin
FAIL_HEX_OUT <= "A";
FAIL_SEG_OUT <= 4'b1011;
state <= midleft;
end
//Rest of statements
endcase
end
always#(FAIL or BIN_IN or FAIL_SEG_OUT or FAIL_HEX_OUT)
begin
if(FAIL == 1) begin
HEX_OUT <= FAIL_HEX_OUT;
SEG_SELECT_OUT <= FAIL_SEG_OUT;
end else begin
case(BIN_IN)
//your statements
endcase
end
end
Additionally, this wont work:
HEX_OUT [6:0] = A;
do this to assign ascii to a reg
HEX_OUT [6:0] = "A";
I also assume that you are using endcase to close your case-statements.
I have made your code-snippet compile here:
http://www.edaplayground.com/x/P_v
Edit:
I changed the sensitivity list on the combinational logic. The above code wouldn't have worked earlier.
Because you have posted so little of your code it is hard to figure out what you actual problem is. I assume that you only have one output port for to control all the 7-segment displays. In that case you need to cycle through each SEG_SELECT_OUT and set HEX_OUT for each display when you wish to output FAIL. This, in turn, implies that each display also has the ability to store the HEX_OUT signal that it receives, and your outputs (probably SEG_SELECT_OUT) must enable the write functionality of these display registers. Check that this is the case. I also assume that your real-time-counter that counts 30 seconds sets the FAIL flag when it completes, and is reset every time the maze(I have no idea what you mean when you say maze) is completed. You say that you need to change the number, and I assume that you are talking about outputting the number in BIN_IN on your display and that BIN_IN is changed elsewhere. All of this should work in the code above.
Without more information it is hard to help any further.

Resources