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
-end
s 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
.