Shift Registers Verilog - verilog

I am very new to HDL language. I have a question about how to program a shift register. (i know i shift to the other direction). Why does the book use wire[N-1:0] r_next? what's drawback of my implementation?
thanks
my first try is as following
module lesson04#(parameter N=8)(
input wire clk, reset,
input wire data,
output wire out
);
reg [N-1: 0] r_reg;
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg =0;
else
r_reg[0]=data;
r_reg = r_reg<<1;
end
assign out =r_reg[N-1];
endmodule
but the book gives:
module lesson04#(parameter N=8)(
input wire clk, reset,
input wire data,
output wire out
);
reg [N-1: 0] r_reg;
wire[N-1:0] r_next;
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg =0;
else
r_reg <= r_next;
end
assign r_next= {data, r_reg[N-1:1]};
assign out =r_reg[N-1];
endmodule

First of all, don't forget your begin-ends around sections of code:
else begin
r_reg[0]=data;
r_reg = r_reg<<1;
end
Without this, only r_reg[0]=data will be in the else clause of the if statement. This will work, but is considered bad style due to the blocking statements in a sequential logic description...
Second, for modeling sequential blocks, use nonblocking assignments (<=) or your calculations may 'fall through' (google nonblocking vs blocking for more info). Your example may very well work (did you try it in a simulator?) but if things get more complicated and more variables are added things can break.
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg <= 0;
else begin // This is horrible! Don't write code like this!
r_reg[0] = data; // blocking
r_reg <= r_reg<<1; // non-blocking
end
end
For the above reason, it is sometimes recommended that combo logic is separated from sequential logic so that you can write nonblocking assignments to registers in sequential blocks, and blocking in combo blocks and never have to worry about the scheduling.
To code in this way, you need to calculate what the next output should be using the current state, hence the r_next bus in the answer. I think it tends to help the synthesis tool out too if all the flip-flops are separated from surrounding combo logic in this way.
Also, if your reset is active low (ie LOW resets ) it should be named as such, eg resetb or reset_n.

Your implementation produces quite a different output from the book's. You should prove this to yourself by constructing a simple testbench to drive your inputs and run a simulation. You will see that the book's output shifts the input data by a single clock cycle, whereas your output shifts the input data by eight clock cycles.
By the way you have indented your always block, I am led to believe that it is not what you wanted. This is how your block really behaves:
always #(posedge clk or negedge reset)
begin
if(!reset) begin
r_reg =0;
end else begin
r_reg[0]=data;
end
r_reg = r_reg<<1;
end
I always explicitly use the begin/end keywords in if/else statements to avoid this confusion.
The way it simulates, r_reg is always 0 because you clobber the 1st assignment (r_reg[0]=data;) with the 2nd (r_reg = r_reg<<1;). Another difference is that the book assigns data to the MSB of the shift register, but you assign it to the LSB.
If you are using decent linting and synthesis tools, you would probably get a bunch of warnings for your code. This would alert you to make some changes.

Related

How to understand the blocking and non blocking statements in verilog?

I understood the basic difference between blocking and non-blocking statements in Verilog. But still it is not possible for me to understand what's happening & when and where to use blocking and non-blocking statements. For example, consider simple d ff code:
module dff (clk, reset,d, q, qb);
input clk;
input reset;
input d;
output q;
output qb;
reg q;
assign qb = ~q;
always #(posedge clk or posedge reset)
begin
if (reset) begin
// Asynchronous reset when reset goes high
q <= 1'b0;
end else begin
// Assign D to Q on positive clock edge
q <= d;
end
end
endmodule
But if I write the very same logic using two-segment coding technique:
module dff(input wire d,
clk,
reset,
en,
output wire q);
reg q;
reg r_reg, r_next;
always #(posedge clk, posedge reset)
if(reset)
r_reg<=1'b0;
else
r_reg<=r_next;
always #*
if(en)
r_reg=d;
else
r_reg=r_next;
assign q<=r_reg;
endmodule
Now, in this code, I just didn't understand why are using <= in the first always block and why they are using = in 2nd always block. I also know that in combinational logic circuit = is advised to use & in sequential <= this is advised to use. But still, I couldn't be able to find out the answer to the usage of blocking and non-blocking statements. Can you please help me!?
Blocking/non-blocking assignments is a simulation artifact only. Contrary to the believe, verilog does not describe hardware. Verilog describes desired behavior of the hardware trying to fit it into an event-driven simulation scheme.
Here is a simple example of a shift register which employs 2 flops:
always #(posedge clk)
out1 = in;
always #(posedge clk)
out2 = out1;
Now, what would the output of the out2 be? Since we are dealing with simulation, then it depends on the order in which these 2 statements are executed. Either it will be the old value of out1, or the new one (actually the value of in);.
In hardware there is no such mess. It will flop the value which existed at the posedge time, the old value of out1 (well, unless there are unusual delays in clocks).
In order to match this behavior, the non-blocking assignment was introduced. Verilog simulation is done in simulation ticks. Every tick is as long as there are events which could cause re-evaluation of other blocks. The non-blocking assignments are scheduled to be executed at the end of such a tick with current rhs values ( in reality there are several scheduling zones). So, consider the following:
always #(posedge clk)
out1 <= in;
always #(posedge clk)
out2 <= out1;
In the above example the all assignments will happen at the end of the tick. 'out2` will be assigned a value which existed at the time of the <=, so, it will be the old value of out1. Now, it does not matter in which order they are executed.
So, the top-level recommendation is to use blocking assignments (=) for combinational logic and use non-blocking assignments (<=) for all outputs of state devices, flops and latches. Note that some temporary variables inside state devices, which are only used there internally should also be assigned with blocking. Also, never use non-blocking assignments in clock trees.

two clock ring counter with verilog

I'm trying to write a roll shift/ ring counter that takes two switches as the clocks in verilog.
My code is as follows:
module roll(CLK1, CLK2, LEDS);
input CLK1;
input CLK2;
output [3:0] LEDS;
reg [3:0] LEDS;
initial
begin
LEDS = 4'b0001;
end
always#(posedge CLK1 or posedge CLK2)
begin
if(CLK1)
begin
LEDS[3]<=LEDS[2];
LEDS[2]<=LEDS[1];
LEDS[1]<=LEDS[0];
LEDS[0]<=LEDS[3];
end
// Roll Right
if(CLK2)
begin
LEDS[3]<=LEDS[0];
LEDS[2]<=LEDS[3];
LEDS[1]<=LEDS[2];
LEDS[0]<=LEDS[1];
end
end
endmodule
I tried using two always blocks, but then figured out that I cannot do that. and when I have the posedge CLK2 in the always statement, the leds on my FPGA all stay on.
Remember Verilog is not a programming language it is a hardware description language.
And when coding for synthesis, you will only be successful if you write code that can be instantiated with actual gates. So writing an always block with sensitivity to edges of two different signals can't be synthesized unless the response to one of the two signals has the effect of a RESET or PRESET operation.
Your code also logically doesn't do what it seems you want to. Consider what your code says will happen if there is a rising edge on CLK2 when CLK1 is already high (or vice versa). Your lights will roll left and then immediately roll right gain, resulting in no change.
A more usual approach would be to have a clock running much faster than the UP and DOWN inputs are expected to change, and use that to drive the logic. For example
module roller(input clk, input rst, input UP, input DOWN, output reg LEDS[3:0]);
reg UP1, DOWN1;
always #(posedge clk or posedge rst)
if (rst) begin
LEDS[3:0] <= 4'b0001;
end
else
begin
UP1 <= UP;
DOWN1 <= DOWN;
if (UP & ~UP1) begin
LEDS[3:0] <= {LEDS[2:0], LEDS[3]};
end
else if (DOWN & ~DOWN1) begin
LEDS[3:0] <= {LEDS[0], LEDS[3:1]};
end
end
endmodule;
Notice that this gives priority to UP. If both UP and DOWN are asserted, the pattern will roll "up" rather than down. If you want a different behavior, you'd have to modify the code to achieve it.

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

Assignment under multiple single edges is not supported for synthesis

I have written this code:
module Key_Schedule(
subkey_tupple1,
subkey_tupple2,
generate_key_final_step,
rst,clk
);
reg [0:31] a1,b1,a2,b2;
input [0:31] subkey_tupple1;
input [0:31] subkey_tupple2;
//input [31:0] subkey_A_swap;
//input [31:0] subkey_B_swap;
input clk,rst;
output reg [0:63] generate_key_final_step;
reg [0:63] temp;
reg [0:63] round_sub_key_left;
always #(posedge clk or negedge rst)
begin
if (!rst)
begin
temp<={64{1'b0}};
round_sub_key_left<={64{1'b0}};
end
else
temp<={subkey_tupple1[0:31],subkey_tupple2[0:31]};
//The error is below... line 49
round_sub_key_left<={temp[8:15],temp[16:23],temp[24:31],temp[0:7],temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a1={temp[8:15],temp[16:23],temp[24:31],temp[0:7]};
b1={temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a2=b1;
b2=a1^b1;
generate_key_final_step={a2,b2};
end
endmodule
When I click Synthesize -XST I get this error:
ERROR:HDLCompiler:1128 - "D:\Embedded_Project\Key_Schedule.v" Line 49: Assignment under multiple single edges is not supported for synthesis
There is a missing begin-end around the else condition. Therefore the assignment to temp is the only assignment in the else condition. When in active reset round_sub_key_left is still derived from temp. There error is likey do to the fact that during asynchronous reset round_sub_key_left is not being assigned to a constant.
Also, at toolic mentioned: It is generally a bad practice to put your combinational logic and synchronous logic in the same always block (ie mix blocking and non-blocking assignments). The best practice is to put combinational logic in an always #* block with blocking assignments (=). Synchronous logic (ie flip-flop) should go in an always #(posedge clk /*+ async-set/set*/) and only use non-blocking assignment (<=).
always #(posedge clk or negedge rst) begin
if (!rst) begin
temp<={64{1'b0}};
round_sub_key_left<={64{1'b0}};
end
else begin
temp <= {subkey_tupple1[0:31],subkey_tupple2[0:31]};
round_sub_key_left <= temp[8:31],temp[0:7],temp[40:63],temp[32:39]};
end
end
always #* begin : output_comb_logic
a1={temp[8:15],temp[16:23],temp[24:31],temp[0:7]};
b1={temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a2=b1;
b2=a1^b1;
generate_key_final_step={a2,b2};
end
else at line 47 affects only one line, and it is not right.
Under reset condition round_sub_key_left has two conflicting drivers.
Place code after else in begin-end parentheses.

Verilog code simulates but does not run as predicted on FPGA

I did a behavioral simulation of my code, and it works perfectly. The results are as predicted. When I synthesize my code and upload it to a spartan 3e FPGA and try to analyze using chipscope, the results are not even close to what I would have expected. What have I done incorrectly?
http://pastebin.com/XWMekL7r
Your problem is with lines 13-16, where you set initial values for state registers:
reg [OUTPUT_WIDTH-1:0] previousstate = 0;
reg [OUTPUT_WIDTH-1:0] presentstate = 1;
reg [6:0] fib_number_cnt = 1;
reg [OUTPUT_WIDTH-1:0] nextstate = 1;
This is an equivalent to writing an "initial" statement assigning these values, which isn't synthesizable -- there is no such thing as a default value in hardware. When you put your design inside an FPGA, all of these registers will take on random values.
Instead, you need to initialize these counters/states inside your always block, when reset is high.
always #(posedge clk or posedge reset)
if (reset) begin
previousstate <= 0;
presentstate <= 1;
... etc ...
end
Answer to the follow-up questions:
When you initialize code like that, nothing at all happens in hardware -- it gets completely ignored, just as if you've put in a $display statement. The synthesis tool skips over all simulation-only constructs, while usually giving you some kind of a warning about it (that really depends on the tool).
Now, blocking and non-blocking question requires a very long answer :). I will direct you to this paper from SNUG-2000 which is probably the best paper ever written on the subject. It answers your question, as well as many others on the topic. Afterward, you will understand why using blocking statements in sequential logic is considered bad practice, and why your code works fine with blocking statements anyway.
http://cs.haifa.ac.il/courses/verilog/cummings-nonblocking-snug99.pdf
More answers:
The usual "pattern" to creating logic like yours is to have two always blocks, one defining the logic, and one defining the flops. In the former, you use blocking statements to implement logic, and in the latter you latch in (or reset) the generated value. So, something like this:
wire some_input;
// Main logic (use blocking statements)
reg state, next_state;
always #*
if (reset) next_state = 1'b0;
else begin
// your state logic
if (state) next_state = some_input;
else next_state = 1'b0;
end
// Flops (use non-blocking)
always #(posedge clock)
if (reset) state <= 1'b0;
else state <= next_state;
Note that I'm using a synchronous reset, but you can use async if needed.
Lines 13-16 are correct. "reg [6:0] fib_number_cnt = 1;" is not the same as using "initial" statement. Read Xilinx synthesis guide for more detailed description of how to initialize the registers.

Resources