shift register using dff verilog - verilog

I want to create a shift register using d-flip-flop as basic structural element.
code:
dff:
module dff(d,q,clk,rst);
input d,clk,rst;
output reg q;
always #(posedge clk)
begin:dff_block
if(rst==1'b1)
q=1'b0;
else
q=d;
end
endmodule
shift register:
module shift_register(s1,d,clk,s0,q);
parameter n=3;
input s1,clk;
input [n:0] d;
output s0;
output [n:0] q;
genvar i;
assign d[3]=s1;
generate
for(i=0; i<=n; i=i+1)
dff U1(.d(d[i]),.q(q[i]),.clk(clk));
endgenerate
assign q[3]=d[2];
assign q[2]=d[1];
assign q[1]=d[0];
assign q[0]=s0;
endmodule
test bench:
module tb();
parameter n=3;
reg [n:0] d;
reg s1,clk;
wire [n:0] q;
wire s0;
shift_register UUT(.s1(s1),.d(d),.clk(clk),.q(q),.s0(s0));
initial begin
d=4'b0000;
clk=0;
end
always
begin:clok
#10 clk=~clk; s1=1;
end
endmodule
I think test bench has the problem.I have tried to give s1 values for every #10 while clk=1 but again does not work.
This code does not give me waveforms for q and s0.I cant find whats wrong.Any ideas?

you have several problems with the code.
q is an output reg of dff; q[i] is passed as q to dff. q[i] gets also assigned in within the assign statement. So, you have multiply driven wire q[i] which most likely gets resolved to x and never changes. You have your i/o swapped around somewhere.
you do not assign anything to s0, so it does not change and does not produce any waveform.
in this particular case blocking assignments within the flop will not pay any role, but in general they could cause unpredictable simulation results. Use non-blocking.
there is not much sense in the generate loop there. You can pass full vectors tot he dff and can flop full vectors as well.
It looks like you get confused int teh direction of the assign statement. It implies direction. assign q[0] = s0; means assign value of s0 to the wire q[0], not vice versa.

Related

How to properly pass data to a submodule and get results back in verilog?

Say I have a submodule and want to "call" it from a top module.
//sub.v
module sub(
input wire clk,
input wire rst_n,
input wire update,//interface is modifiable
input wire [7:0] in_data,
output wire[7:0] out_data
);
reg[7:0] state;
always #(posedge clk) begin
if(!rst_n)
state<=0;
else if(update)
state<=state+in_data;//update drives states to change according to input data
end
assign out_data=state<<1;
endmodule
//top.v
module top(
input wire clk,
input wire rst_n,
output reg[7:0] top_out
);
//Submodule
reg sub_update;
reg[7:0] sub_in;
wire[7:0] sub_out;
sub sub_instance(
.clk(clk),
.rst_n(rst_n),
.update(sub_update),
.in_data(sub_in),
.out_data(sub_out)
);
//Topmodule
reg[7:0] top_state;
localparam STATE0 = 8'd0;
localparam STATE1 = 8'd1;
localparam STATE2 = 8'd2;
localparam STATE3 = 8'd3;
localparam TEMP_STATE = -8'd1;
always #(posedge clk) begin
if(!rst_n) begin
top_state <= STATE0;
sub_update <= 0;
sub_in <= 0;
end else begin
case (top_state)
STATE0:top_state<=STATE1;
STATE1:begin
//want to update the submodule and use its output here
sub_in <= 123;
sub_update <= 1;
top_state <= TEMP_STATE;
end
STATE2:top_state<=STATE3;//proceed from STATE1
TEMP_STATE:begin
sub_update <= 0;
top_out <= sub_out+1;
top_state <= STATE2;
end
default:top_state<=STATE0;
endcase
end
end
endmodule
The main question may divide into 2 smaller questions:
In my module code, the "update" signal is both set and captured at the same edge of a same clock. Is that a data race? Should I use a different edge, or pass a reverse clock to the submodule? Or should I change "update" to other interface?
Is there a better way to get the submodule output than using a temporary state? For this simple example, there is a way to calculate the output when the input is ready: Inline everything, get top_out<=((state+123)<<1)+1; at STATE1. Can this be generalized for more complicated calculation?
there is no problem in setting and capturing 'update' on the same clock edge. Just note that it will be captured with a delay of one clock cycle after it is set. This is the way flops work and your simulation should work same way because you did correctly use NBAs.
This is the question that you should answer for yourself. Better ways or not depend on your requirements and abilities of hardware. You have all these parts of the equation and states for some reason. You can probably collapse them if your algorithm allows it. You can use complex calculations there if they do not violate your design rules.

Bidirectional shifting using multiplexers

Edit:Only by the screenshots(http://prntscr.com/lv3uqw http://prntscr.com/lv3yhf) and my code below you can still understand my goal here just incase you dont want to read the text.
I am trying to write a verilog code for a universal shift register. My original register was working properly(the one without the LR_bar signal). But on this one i have no idea how i can make this conection(mux with ff) happen http://prntscr.com/lv3uqw and http://prntscr.com/lv3yhf.I had a suggestion that the for loop should start from -1 but i still cant find a solution. I would also like to avoid the h signal if possible(maybe we also use the w there). So basicly when LR_bar=1 i want the shift register to shift left and when =0 to shift right.
Tip for the screenshot: ser in l_sh stands for serial input for left shifting
(Also found that on a Mano Morris 3rd edition(6th is more detailed) book (Computer Design Fundamentals) which is, to a point , a little close to what i want. But i want 2to1 multiplexers . But the 2 first screenshots is what i want to achieve.
http://prntscr.com/lvb5bt http://prntscr.com/lvb65f )
I think i describe it well...can someone solve this?
MY NEW CODE(below) AND TEST AFTER SOME VALUES......http://prntscr.com/lvhk63
I TRIED TO MIMIC THAT(http://prntscr.com/lvgx31 http://prntscr.com/lvgxgw http://prntscr.com/lvgxkw) BUT ONLY FOR THE SERIAL INPUT PART(MSB,LSB). PLEASE TELL ME WHERE IM WRONG. THANKS
the output should be the state of the register
-----------------------------------------------------------
module lr_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
wire [n+1:0] w;
wire [n-1:0] mux_out;
genvar i;
assign w[0]=in;
assign w[n+1]=in;
generate
for(i=0;i<n;i=i+1)
begin
mux2to1 MUX(.in({w[i],w[i+2]}),.sel(LR_bar),.out(mux_out[i]));
dff ff1(.d(mux_out[i]), .q(w[i+1]), .clk(clk),
.rst(rst));
end
endgenerate
assign out=w[n:1];
endmodule
------------------------------------------------------------
JUST AN ATTEMPT NOTHING TO LOOK
module lr_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
wire [n+1:0] w;
wire mux_out;
genvar i;
assign w[0]=in;
assign w[n+1]=in;
generate
for(i=-1;i<n-1;i=i+1)
begin
mux2to1 MUX(.in({w[i+1],w[3+i]}),.sel(LR_bar),.out(mux_out));
dff ff1(.d(mux_out), .q(out[i+1]), .clk(clk),
.rst(rst));
end
endgenerate
------------------------------------------------------------
module dff (d, q, clk, rst);
input d, clk, rst;
output reg q;
always # (posedge clk) begin : dff_block
if (rst==1'b1)
q = 1'b0;
else
q = d;
end
endmodule
module mux2to1(in, sel, out) ;
input [1:0] in;
input sel;
output reg out;
always #(*)
case(sel)
1'b0: out=in[0];
1'b1: out=in[1];
endcase
endmodule
module shreg_n(in, out, clk, rst);
parameter n=4;
input in, rst, clk;
output [n-1:0] out;
wire [n:0] w;
genvar i;
assign w[0]=in;
generate
for(i=0;i<n;i=i+1)
dff ff1(.d(w[i]), .q(w[i+1]), .clk(clk),
.rst(rst));
endgenerate
assign out=w[n:1];
//assign out=w[n];
endmodule
Blocking assignments might work in your specific case. As a matter of clean coding style and preventing any issues in the future, always use <= for all output assignments in flops (and latches).
Now, let's see what you want to do:
w = out; // to keep the immediate values and avoid ordering issues
for left shift: w[3] -> x, w[2] -> out[3], w[1] -> out[2], w[0] -> out[1] , in -> out[0]
for right shift: w[0] -> x, w[1] -> out[0], w[2] -> out[1], w[3] -> out[2], in -> out[3]
so, with a mux, say for out[2]i == 2, you would need a mux which does this:
- w[1] -
-> out[2]
- w[3] -
mux2to1 (.in({out[i+1], out[i-1]}), .sel(LR_sel), .out(out[i]));
you also need to take care of special cases [0] with left shift and [n-1] with the right shift. For simplicity,
you can use if statement in the generate block to handle it.
if (i == 0)
mux2to1 MUX0(.in({in, w[1]}), .sel(LR_bar), .out(tmp[0]));
else if (i == n-1)
mux2to1 MUXN(.in({w[n-2], in}), .sel(LR_bar), .out(tmp[n-1]));
.out(out[i]));
else
mux2to1 (.in({out[i-1], out[i+1]}), .sel(LR_sel), .out(out[i]));
Basically it creates yet another mux for those special cases, so that you have more of them.
As for the flop, there are at least 2 ways to approach it. You can flop results before or after the mux.
for the flopping before the mux (which i assumed in the above explanation), you just do
always #(posedge clk)
if (rst)
w <= 4'b0;
else
w <= out;
to do it after the mux, you would need to switch out and w and then flop w into out. You can do a bit-by-bit flop as you did, but it makes the program more crowded in my opinion. Also it causes verilog to generate multiple one-bit flops which might affect simulation performance.
Another approach for shift registers with the flop is to something like the following:
always #(posegde clk) begi
if (rst)
out <= 4'b0;
else if (LR_bar) begin
out <= {out[2:0], in};
end
else begin
out <= {in, out[3:1]};
end
end
The above simplifies the code significantly. BTW, you would have an issue if you use blocking assignments there.
Edit 1
I modified your code to a workable condition down here based on my comments.
you need a register w to keep the shift register value. You need the tmp to connect the mux with the flop. w is the output of the flop.
module uni_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
reg [n-1:0] w; // keep the value of the register shift
wire [n-1:0] tmp;
genvar i;
mux2to1 MUX0(.in({in,w[1]}), .sel(LR_bar), .out(tmp[0]));
mux2to1 MUXN(.in({w[n-2], in}), .sel(LR_bar), .out(tmp[n-1]));
generate
for(i=0;i<n;i=i+1) begin
if (i > 0 && i < n-1) begin: loop
mux2to1 MUX(.in({w[i-1], w[i+1]}), .sel(LR_bar), .out(tmp[i]));
end
dff ff1(.d(tmp[i]), .q(w[i]), .clk(clk), .rst(rst));
end
endgenerate
assign out = w;
endmodule

How to modify the Verilog code to avoid multiple drivers?

Quartus 11.0 says:
Error (10028): Can't resolve multiple constant drivers for net "n[9]"
for the following code:
module make_counter(h, clk, P);
input wire h;
input wire clk;
output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;
always #(posedge h)
begin
n<=0;
end
always #(negedge clk)
begin
if(n<600)
n<=n+1'b1;
if(n==106)
r<=1'b0;
else if(n==517)
r<=1'b1;
else;
end
assign P=r;
endmodule
########### image is here ###########
zhe image is what i want. when flag1 start set n=0, and count clk;
when count to flag2, set P=0; when count to red arrow, set P=1;
Assuming h is synchronous to clk, simply sample h and figure out when the sample value is low and the current value is high (e.g. h rose). This way n is assigned within one always block (which is required for synthesis) and everything is is the same clocking domain.
always #(negedge clk) begin
past_h <= h;
if(!past_h && h) begin // detect 0->1
n <= 10'h000;
end
else begin
n <= n + 1'b1;
end
end
If h is asynchronous, then things get more complicated to keep the signal clean. In which case I recommend reading Clock Domain Crossing (CDC) Design & Verification Techniques by Cliff Cummings
As the warning says, there are multiple drivers for n[9], and actually all of n and r, since n and r are both driven in the initial and the always, and when synthesizing the design, there can be only one driver for a reg. And n is driven in multiple always blocks.
For synthesis, a reg should be driven from only one always block.
For the multiple always blocks where n is driven, combine these to only one, and use only one clock, e.g. clk.
If the purpose is to assign a default value for n and r, then make that in the declaration, and remove the initial, like:
reg r = 1'b1;
reg[9:0] n = 0;
However, consider adding a reset signal if possible, then then use this reset signal to assign reset values to the regs, either synchronously or asynchronously.
You can try to move the posedge h into the same always block as the negedge clock and sample h and clk based on the input logic. If h goes low before the negedge of clk then something like this may work.
module make_counter(h, clk, P);
input wire h;
input wire clk;
output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;
always #(negedge clk, posedge h)
begin
if(h==1'b1)
n<=0;
if(n<600)
n<=n+1'b1;
if(n==106)
r<=1'b0;
else if(n==517)
r<=1'b1;
else;
end
assign P=r;
endmodule
i think it will help you out. i have compiled this one in xilinx 14.5 synthesis is done.
module make_counter(h, clk, P);
input wire h;
input wire clk;
output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;
task cpu_write;
begin
# (posedge h);
n <= 0;
# (posedge clk);
if(n<600)
n<=n+1'b1;
if(n==106)
r<=1'b0;
else if(n==517)
r<=1'b1;
else;
end
endtask
assign P=r;
endmodule

Parameterized number of cycle delays in verilog?

I have to delay a few control signals in a pipeline I've designed by the number of stages in the pipeline. This is obviously very straight forward -- just put N flip-flops in between the the input signal and output signal. I'm wondering if there's a way to parameterize N. If I ever change the number of stages in the pipeline I have to go back and add/remove flip-flops, which is sort of annoying. I thought about just writing a script to read a define somewhere and generate the module, but that seems like overkill. Is a genvar loop the right way to go here?
You could use a parameterized shift register to do this. Something like:
module shift
(
input clk,
input data_in,
output data_out
);
parameter DEPTH = 3;
reg [DEPTH-1:0] holding_register;
always # (posedge clk) begin
holding_register <= {holding_register[DEPTH-2:0], data_in};
end
assign data_out = holding_register[DEPTH-1];
endmodule
Another alternative would be to use a generate statement to create essentially the same effect.
Here is how to created the parameterized shift register using a generate block and a DFF module. It even works with DEPTH=0 and DEPTH=1.
module shift
(
input clk,
input reset,
input data_in,
output data_out
);
parameter DEPTH = 3;
wire [DEPTH:0] connect_wire;
assign data_out = connect_wire[DEPTH];
assign connect_wire[0] = data_in;
genvar i;
generate
for (i=1; i <= DEPTH; i=i+1) begin
dff DFF(clk, reset,
connect_wire[i-1], connect_wire[i]);
end
endgenerate
endmodule
Complete working code with a test on EDA Playground: http://www.edaplayground.com/s/4/50

Verilog Random Number Generator

I'm new to Verilog and I'm trying to create a 4-bit binary Random Number Generator. The program is as follows, could anyone help me by mentioning the errors?
I initially tried out this:
module rng (d);
inout[3:0]d;
//wire[3:0]d;
//input clk, rst;
//wire [3:0] w;
dff f1(a[0],clk,d[0],rst);
dff f2(a[1],clk,d[1],rst);
dff f3(a[2],clk,d[2],rst);
dff f4(a[3],clk,d[3],rst);
xorper p(d[0],d[1],d[2],d[3],a[0],a[1],a[2],a[3]);//permutations
//dff f1(a,clk,q,rst);
dff x(d,clk,q,rst);
endmodule
I also tried out this:
module re(b,q,clk,rst);
input [3:0]q;
input clk,rst;
wire [3:0]q,a;
output [3:0]b;
reg [3:0]b;
rox f1(q[0],q[1],q[2],q[3],a[0],a[1],a[2],a[3]);//permutations
rod f2(a,clk,b,rst);//dff
always#(posedge clk) begin
if (rst==1'b0) begin
b[0]=q[0];
b[1]=q[1];
b[2]=q[2];
b[3]=q[3];
end else if(rst==1'b1)
b[0]=1'bx;
b[1]=1'bx;
b[2]=1'bx;
b[3]=1'bx;
end
endmodule
I would suggest starting with an LFSR for random number generation. They are a straight forward shift register, with taps back to a mutlibit XOR to create the feedback bit.
Your implementation of a flop could be better.
1) Add negedge rst to the sensitivity list
2) You do not want to assign x's
3) use non-blocking assignments (<=)
reg [3:0] b;
//LFSR feedback bit
wire feedback
assign feedback = b[0] ^ b[3];
// Add active low reset to sensitivity list
always#(posedge clk or negedge rst) begin
if (rst==1'b0) begin
b[3:0]<=4'hF; //reset condition first
end
else begin
b[0]<=feedback;
b[1]<=b[0];
b[2]<=b[1];
b[3]<=b[2];
//Alternative Verilog might be
// b = {b[2:0], feedback};
end
For choosing tap point for an LFSR search for a maximal length LFSR. A maximal LFSR will have the longest number sequence before it repeats for a given length of register and tap points.

Resources