Shift Register Design using Structural Verilog outputs X - verilog

I am designing a shift register using hierarchical structural Verilog. I have designed a D flip flop and an 8 to 1 mux that uses 3 select inputs. I am trying to put them together to get the full shift register, but my output only gives "XXXX" regardless of the select inputs.
Flip Flop Code
module D_Flip_Flop(
input D,
input clk,
output Q, Q_bar
);
wire a,b,c,d;
nand(a,D,b);
nand(b,a,clk,d);
nand(c,a,d);
nand(d,c,clk);
nand(Q,d,Q_bar);
nand(Q_bar,b,Q);
endmodule
8 to 1 Mux
module Mux8to1(
input [2:0]S,
input A,B,C,D,E,F,G,H,
output Out
);
wire a,b,c,d,e,f,g,h;
and(a, A,~S[2],~S[1],~S[0]);
and(b, B,~S[2],~S[1],S[0]);
and(c, C,~S[2],S[1],~S[0]);
and(d, D,~S[2],S[1],S[0]);
and(e, E,S[2],~S[1],~S[0]);
and(f, F,S[2],~S[1],S[0]);
and(g, G,S[2],S[1],~S[0]);
and(h, H,S[2],S[1],S[0]);
or(Out, a,b,c,d,e,f,g,h);
endmodule
Hierarchical Combination of the Two
module shiftRegister_struct(
input clk,
input [2:0]S,
input [3:0]L,
output reg [3:0]V
);
wire a,b,c,d;
wire V_bar[3:0];
Mux8to1 stage3(S[2:0],V[3],V[0],V[2],1'b0,V[2],V[3],V[2],L[3],a);
Mux8to1 stage2(S[2:0],V[2],V[3],V[1],V[3],V[1],V[3],V[1],L[2],b);
Mux8to1 stage1(S[2:0],V[1],V[2],V[0],V[2],V[1],V[2],V[1],L[1],c);
Mux8to1 stage0(S[2:0],V[0],V[1],V[3],V[1],1'b0,V[1],1'b0,L[0],d);
D_Flip_Flop stage3b(a,clk,V[3],V_bar[3]);
D_Flip_Flop stage2b(b,clk,V[2],V_bar[2]);
D_Flip_Flop stage1b(c,clk,V[1],V_bar[1]);
D_Flip_Flop stage0b(d,clk,V[0],V_bar[0]);
end module
Any thoughts on what might be screwing up my output? The output is V[3:0].
I should also include my test bench code:
module Shift_Test_Bench;
// Inputs
reg [2:0] S;
reg [3:0] L;
reg clk;
integer i;
integer j;
// Outputs
wire [3:0] V;
// Instantiate the Unit Under Test (UUT)
shiftRegister_struct uut (
.clk(clk),
.S(S),
.L(L),
.V(V)
);
initial begin
// Initialize Inputs
S = 7;
L = 3;
clk = 1;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
for(i = 0; i < 16; i = i+1)
begin
S = i;
for(j = 0; j < 2; j = j+1)
begin
clk = !clk;
#5;
end
end
end
endmodule

You have a wiring bug in your D_Flip_Flop module. When I simulated your testbench, I got compiler warnings:
Implicit wire 'f' does not have any driver, please make sure this is
intended.
Implicit wire 'e' does not have any driver, please make sure this is
intended.
Here are the lines:
nand(Q,d,f);
nand(Q_bar,b,e);

Your missing a reset condition, either synchronous or asynchronous. Your flops have an unknown value and never reach known state because the data input is dependent on the flop output. By adding a reset to can put the flops into a known state independent of its outputs (V/V_bar).
In this case adding a synchronous is be easier. Simply add some 2-to-1 muxes and a new reset pin.
Mux2to1 syncrst3(a_d,a,1'b0,reset);
// ...
D_Flip_Flop stage3b(a_d,clk,V[3],V_bar[3]);
// ...

Related

How do I generate N counters inside a generate block to load test an FPGA?

I need to estimate the maximum number of 16-bit counters that a FPGA board can fit. I created a 16-bit counter module with enable (en) and terminal count (TC), and instantiated this inside a generate block in a top level module. However, I need to generate these counters in a chain where the TC output of one acts as the enable for the next counter in the chain. I'm unable to figure out the logic for this. Can anyone help me ?
16-bit counter code:
module counter_16 (clk, Q, TC, en);
input clk, en;
output [15:0] Q;
output TC;
wire clk, en;
reg [15:0] Q = 0; //initial value for the output count
reg TC;
always #(posedge clk)
begin
if(en == 1)
begin
Q <= Q+1;
end
TC = &Q; //TC is 1 when all bits of Q is high
end
endmodule
Counter generation module:
module counter_generator
#(
parameter n = 10
)
(output [15:0] cnt_out,
output TC,
input clk, en);
wire [n-1:0] temp_en;
temp_en[0] <= 0;
wire [15:0] temp_out;
generate
genvar i;
for(i=1;i<=n;i=i+1)
begin : counter_identifier
counter_16 counter_16_gen (
.clk(clk),
.Q(temp_out),
.TC(temp_en[i-1]),
.en(en));
end
endgenerate
endmodule
The first thing to do is make the loop start from 0, not 1, so that the signal indexes align.
Create a signal tc_out that is n bits wide and connect that directly to the TC port in the generate block, using the index [i]. TC of instance 0 is connected to tc_out[0], etc. This is straightforward, and it helps us with the en connections.
Create a signal temp_en that is also n bits wide and connect that directly to the en port in the generate block. The key is to assign this signal to the tc_out signal as seen below.
en of instance 0 is driven by the en input of counter_generator
en of instance 1 is driven by the TC output of instance 0
en of instance 2 is driven by the TC output of instance 1
etc.
Lastly, create an array of n 16-bit wires, temp_out, and connect that directly to the Q port in the generate block.
module counter_generator
#(
parameter n = 10
)
(
output [15:0] cnt_out,
output TC,
input clk, en
);
wire [n-1:0] tc_out;
wire [n-1:0] temp_en = {tc_out[n-2:0], en};
wire [15:0] temp_out [n];
assign TC = temp_out[n-1];
generate
genvar i;
for (i=0; i<n; i=i+1) begin : counter_identifier
counter_16 counter_16_gen (
.clk (clk),
.Q (temp_out[i]),
.TC (tc_out [i]),
.en (temp_en [i])
);
end
endgenerate
endmodule

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

Verilog: Cannot Attach Register As Output?

I am trying to compile my module and it works fine when I remove the badData register from the testbench. However, the moment I add it, verilog complains "Error loading design".
Module Code:
module hamming_code #( parameter TOTAL_LENGTH = 15,
parameter PARITY_BITS = 4
)
(
//inputs
input [TOTAL_LENGTH-1:0] codeword,
//outputs
output [TOTAL_LENGTH-1:0] correctedWord,
output reg badData
);
Testbench code:
`timescale 1ns/1ps
module tb ();
integer pass_count, fail_count;
reg clock;
reg [14:0] cw;
wire [14:0] ccw;
reg error;
integer i;
hamming_code uut (// Inputs
.codeword(cw),
// Outputs
.correctedWord(ccw),
.badData(error)
);
initial begin
// initial values
clock <= 0;
pass_count <= 0;
fail_count <= 0;
error <= 0;
wait(0);
end
always#(*)
#5 clock <= ~clock;
endmodule
BadData is an output from your uut.
It should be connected to a wire in the TB. Also it shouldn't be assigned any value in TB (you are assigning a 0).
When you remove reg error, Its automatically inferred as a wire. that's why there is no error.

Pipelined design issues with Verilog

I just started learning Verilog because I bought an FPGA. Since I don't have my FPGA yet, I started off with a somewhat big project, just to see where I get. I may have bitten off more than I can chew on this one, but I am trying to make a simple pipelined CORDIC module. The problem I am having in simulation here is that values will propagate from the testbench's input to uut, the unit under test, an instance of cordic rotator, those signals propagate to the first stage in the pipeline, xpipe[0], ypipe[0], zpipe[0], then to a cordic_stage instance, but the outputs of this cordic_stage instance do not seem to be changing any values in the xpipe[1], ypipe[1], or zpipe[1] registers, they remain at zzzz. Now I'm sure there's a million and one things wrong with my modules here, but I want to figure them out on my own. What I do want to know is why the values aren't making it out of the cordic_stage into the next element in the pipelines' arrays, and how I can fix it. Here is my code below:
module cordic_stage #(
parameter ANGLE_WIDTH = 16,
parameter VALUE_WIDTH = 8,
parameter STAGE_I = 0
)(
input clk,
input [VALUE_WIDTH-1:0] xin,
input [VALUE_WIDTH-1:0] yin,
input [ANGLE_WIDTH-1:0] zin,
output reg [VALUE_WIDTH-1:0] xout,
output reg [VALUE_WIDTH-1:0] yout,
output reg [ANGLE_WIDTH-1:0] zout
);
parameter DELTA = 1 << (ANGLE_WIDTH - 2);
always #(posedge clk) begin
if (zin[ANGLE_WIDTH-1]) begin
xout <= xin + (yin >> STAGE_I); // These assignments to outputs are WORKING
yout <= yout - (xin >> STAGE_I);
zout <= zin + (DELTA >> STAGE_I);
end else begin
xout <= xin - (yin >> STAGE_I);
yout <= yout + (xin >> STAGE_I);
zout <= zin - (DELTA >> STAGE_I);
end
end
endmodule
module cordic_rotator #(
parameter ANGLE_WIDTH = 16,
parameter VALUE_WIDTH = 8
)(
input clk,
input [ANGLE_WIDTH-1:0] angle,
input [VALUE_WIDTH-1:0] xin,
input [VALUE_WIDTH-1:0] yin,
output [VALUE_WIDTH-1:0] xout,
output [VALUE_WIDTH-1:0] yout
);
reg [VALUE_WIDTH-1:0] xpipe [ANGLE_WIDTH:0]; // The second element in these pipelines arrays at index 1 never gets changed, so that it NOT WORKING
reg [VALUE_WIDTH-1:0] ypipe [ANGLE_WIDTH:0];
reg [ANGLE_WIDTH-2:0] zpipe [ANGLE_WIDTH:0];
always #(*) begin
xpipe[0] <= angle[ANGLE_WIDTH-1] ? -xin : xin; // These assignments to the first element in the pipeline are WORKING
ypipe[0] <= angle[ANGLE_WIDTH-1] ? -yin : yin;
zpipe[0] <= angle[ANGLE_WIDTH-2:0];
end
genvar i;
generate
for (i = 0; i < ANGLE_WIDTH; i = i + 1) begin: stages
cordic_stage #(ANGLE_WIDTH-1, VALUE_WIDTH, i) stage(clk, xpipe[i], ypipe[i], zpipe[i], xpipe[i+1], ypipe[i+1], zpipe[i+1]); // Values are being passed from the first stage in the pipeline at index zero to the first cordic_stage module, so that is WORKING
end
endgenerate
endmodule
module cordic_rotator_testbench;
// Inputs
reg clk;
reg [3:0] angle;
reg [3:0] xin;
reg [3:0] yin;
// Outputs
wire [3:0] xout;
wire [3:0] yout;
// Instantiate the Unit Under Test (UUT)
cordic_rotator #(4,4) uut (
.clk(clk),
.angle(angle),
.xin(xin),
.yin(yin),
.xout(xout),
.yout(yout)
);
initial begin
// Initialize Inputs
clk = 0;
angle = 0;
xin = 0;
yin = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
assign angle = 2; // These lines are also WORKING
assign xin = 8;
assign yin = 0;
end
always #5 clk = !clk;
endmodule
You are driving a register xpipe, directly from an output wire of a module, I would have thought that would be a syntax error, as register types are only supposed to be driven in procedural blocks.
You might try changing the xyzpipe types from reg to wire, since wire types are what are supposed to be driven by module outputs.
Addendum by OP:
Code in cordic_rotator is changed for wire types, this fixes the problem.
wire [VALUE_WIDTH-1:0] xpipe [ANGLE_WIDTH:0];
wire [VALUE_WIDTH-1:0] ypipe [ANGLE_WIDTH:0];
wire [ANGLE_WIDTH-2:0] zpipe [ANGLE_WIDTH:0];
assign xpipe[0] = angle[ANGLE_WIDTH-1] ? -xin : xin;
assign ypipe[0] = angle[ANGLE_WIDTH-1] ? -yin : yin;
assign zpipe[0] = angle[ANGLE_WIDTH-2:0];

How to sign-extend a number in Verilog

I'm working on a simple sign-extender in Verilog for a processor I'm creating for Computer Architecture.
Here's what I've got so far: [EDIT: Changed the selection statement slightly]
`timescale 1ns / 1ps
module SignExtender( CLK, extend, extended );
input[7:0] extend;
input CLK;
output[15:0] extended;
reg[15:0] extended;
wire[7:0] extend;
always
begin
while (CLK == 1)
extended[7:0] = extend[7:0];
extended[15:8] = {8{extend[7]}};
end
endmodule
I added the while (CLK == 1) thinking that would solve my problem, which I believe is an infinite loop. When I try to test this in iSim, the circuit never initializes.
I also tried removing the copying syntax and just doing extended[8] = extend[7] etc. for [8]-[15], but the same result occurs, so I'm pretty sure that the innermost syntax is correct.
Here's the test file:
`timescale 1ns / 1ps
module SignExtender_testbench0;
// Inputs
reg [7:0] extend;
reg CLK;
// Outputs
wire [15:0] extended;
// Instantiate the Unit Under Test (UUT)
SignExtender uut (
.extend(extend),
.extended(extended)
);
initial begin
// Initialize Inputs
extend = 0;
#100; // Wait 100 ns for global reset to finish
extend = -30;
CLK = 1;
#10;
CLK = 0;
if (extended == -30)
$display("okay 1");
else
$display("fail 1");
extend = 40;
#10;
if (extended == 40)
$display("okay 2");
else
$display("fail 2");
end
endmodule
Any ideas how I can do this successfully?
You nearly got it...
always #( posedge clk ) begin
extended[15:0] <= { {8{extend[7]}}, extend[7:0] };
end
You're also missing a clock edge for the '40' test. Try this, & let me know how you get on...
We can use the syntax $signed to sign extend
module signextender(
input [7:0] unextended,//the msb bit is the sign bit
input clk,
output reg [15:0] extended
);
always#(posedge clk)
begin
extended <= $signed(unextended);
end
endmodule
By the way your module assign is pure combinational so it should not contain a clk, this is another way of doing your module:
module sign_ext
(
unextend,
extended
);
input [15:0] unextend;
output [31:0] extended;
assign extended = {{16{unextend[15]}}, unextend};
endmodule
//TB
module tb_sign_ext;
reg [15:0] unex;
wire [31:0] ext;
sign_ext TBSIGNEXT
(
.unextend(unex),
.extended(ext)
);
initial
begin
unex = 16'd0;
end
initial
begin
#10 unex = 16'b0000_0000_1111_1111;
#20 unex = 16'b1000_0000_1111_1111;
end
endmodule
;)

Resources