How to modify the Verilog code to avoid multiple drivers? - verilog

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

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

Two module verilog is not working

module rff_try_1(q,inp,clk);
input clk,inp;
output q;
reg q;
DFF dff0(q,inp,clk);
endmodule
module DFF(q,inp,clk);
input inp,clk;
output q;
reg q;
always # (posedge clk)begin
if(clk)begin
q=inp;
end
end
endmodule
here I'm using two modules but output is not coming
I'm trying to make two bit right shift register but 1st i have to make one single bit register but even this is not working
There are several mistakes in the code.
1) The line if(clk)begin and relevant end should be removed, posedge clk already describes trigger condition of the flip-flop.
2) A non-blocking assignment (<=) is required for the sequential logic.
The always block should be as follows:
always # (posedge clk) begin
q <= inp;
end
3) Some simulators don't complain, but signal q should be wire in module rff_try_1.
wire q;
Simulation
I simulated the code (after the modifications) on EDA Playground with the testbench below. Used Icarus Verilog 0.9.7 as simulator.
module tb();
reg clk = 1;
always clk = #5 ~clk;
reg inp;
wire q;
rff_try_1 dut(q, inp, clk);
initial begin
inp = 0;
#12;
inp = 1;
#27;
inp = 0;
#24;
inp = 1;
end
initial begin
$dumpfile("dump.vcd"); $dumpvars;
#200;
$finish;
end
endmodule
The signal q is as expected as seen on the waveform.

4 bit countetr using verilog not incrementing

Sir,
I have done a 4 bit up counter using verilog. but it was not incrementing during simulation. A frequency divider circuit is used to provide necessory clock to the counter.please help me to solve this. The code is given below
module my_upcount(
input clk,
input clr,
output [3:0] y
);
reg [26:0] temp1;
wire clk_1;
always #(posedge clk or posedge clr)
begin
temp1 <= ( (clr) ? 4'b0 : temp1 + 1'b1 );
end
assign clk_1 = temp1[26];
reg [3:0] temp;
always #(posedge clk_1 or posedge clr)
begin
temp <= ( (clr) ? 4'b0 : temp + 1'b1 );
end
assign y = temp;
endmodule
Did you run your simulation for at least (2^27) / 2 + 1 iterations? If not then your clk_1 signal will never rise to 1, and your counter will never increment. Try using 4 bits for the divisor counter so you won't have to run the simulation for so long. Also, the clk_1 signal should activate when divisor counter reaches its max value, not when the MSB bit is one.
Apart from that, there are couple of other issues with your code:
Drive all registers with a single clock - Using different clocks within a single hardware module is a very bad idea as it violates the principles of synchronous design. All registers should be driven by the same clock signal otherwise you're looking for trouble.
Separate current and next register value - It is a good practice to separate current register value from the next register value. The next register value will then be assigned in a combinational portion of the circuit (not driven by the clock) and stored in the register on the beginning of the next clock cycle (check code below for example). This makes the code much more clear and understandable and minimises the probability of race conditions and unwanted inferred memory.
Define all signals at the beginning of the module - All signals should be defined at the beginning of the module. This helps to keep the module logic as clean as possible.
Here's you example rewritten according to my suggestions:
module my_counter
(
input wire clk, clr,
output [3:0] y
);
reg [3:0] dvsr_reg, counter_reg;
wire [3:0] dvsr_next, counter_next;
wire dvsr_tick;
always #(posedge clk, posedge clr)
if (clr)
begin
counter_reg <= 4'b0000;
dvsr_reg <= 4'b0000;
end
else
begin
counter_reg <= counter_next;
dvsr_reg <= dvsr_next;
end
/// Combinational next-state logic
assign dvsr_next = dvsr_reg + 4'b0001;
assign counter_next = (dvsr_reg == 4'b1111) ? counter_reg + 4'b0001 : counter_reg;
/// Set the output signals
assign y = counter_reg;
endmodule
And here's the simple testbench to verify its operation:
module my_counter_tb;
localparam
T = 20;
reg clk, clr;
wire [3:0] y;
my_counter uut(.clk(clk), .clr(clr), .y(y));
always
begin
clk = 1'b1;
#(T/2);
clk = 1'b0;
#(T/2);
end
initial
begin
clr = 1'b1;
#(negedge clk);
clr = 1'b0;
repeat(50) #(negedge clk);
$stop;
end
endmodule

Circuit behaves poorly in timing simulation but alright in behavioral - new to verilog

I'm new to verilog development and am having trouble seeing where I'm going wrong on a relatively simple counter and trigger output type design.
Here's the verilog code
Note the code returns the same result whether or not the reg is declared on the output_signal without the internal_output_buffer
`timescale 1ns / 1ps
module testcounter(
input wire clk,
input wire resetn,
input wire [31:0] num_to_count,
output reg [7:0] output_signal
);
reg [31:0] counter;
initial begin
output_signal = 0;
end
always#(negedge resetn) begin
counter = 0;
end
always#(posedge clk) begin
if (counter == num_to_count) begin
counter = 0;
if (output_signal == 0) begin
output_signal = 8'hff;
end
else begin
output_signal = 8'h00;
end
end
else begin
counter = counter + 1;
end
end
assign output_signal = internal_output_buffer;
endmodule
And the code is tested by
`timescale 1ns / 1ps
module testcounter_testbench(
);
reg clk;
reg resetn;
reg [31:0] num_to_count;
wire [7:0] output_signal;
initial begin
clk = 0;
forever #1 clk = ~clk;
end
initial begin
num_to_count = 20;
end
initial begin
#7 resetn = 1;
#35 resetn = 0;
end
testcounter A1(.clk(clk),.resetn(resetn),.num_to_count(num_to_count),.output_signal(output_signal));
endmodule
Behavioral simulation looks as I expected
But the timing simulation explodes
And for good measure: the actual probed execution blows up and looks like
Any tips would be appreciated. Thanks all.
The difference between the timing and functional simulations is that a timing simulation models the actual delay of logic gates while the functional simulation just checks if values are correct.
For e.g. if you have a simple combinational adder with two inputs a and b, and output c. A functional simulation will tell you that c=a+b. and c will change in the exact microsecond that a or b changes.
However, a timing simulation for the same circuit will only show you the result (a+b) on c after some time t, where t is the delay of the adder.
What is your platform? If you are using an FPGA it is very difficult to hit 500 MHz. Your clock statement:
forever #1 clk = ~clk;
shows that you toggle the clock every 1ns, meaning that your period is 2ns and your frequency is 500MHz.
The combinational delay through FPGA resources such as lookup tables, multiplexers and wire segments is probably more than 2ns. So your circuit violates timing constraints and gives wrong behaviour.
The first thing I would try is to use a much lower clock frequency, for example 100 MHz and test the circuit again. I expect it to produce the correct results.
forever #5 clk = ~clk;
Then to know the maximum safe frequency you can run at, look at your compilation reports in your design tools by running timing analysis. It is available in any FPGA CAD tool.
Your code seems working fine using Xilinx Vivado 14.2 but there is only one error which is the following line
assign output_signal = internal_output_buffer;
You can't assign registers by using "assign" and also "internal_output_buffer" is not defined.
I also personally recommend to set all registers to some values at initial. Your variables "resetn" and "counter" are not assigned initially. Basicly change your code like this for example
reg [31:0] counter = 32'b0;
Here is my result with your code:
Your verilog code in the testcounter looks broken: (a) you're having multiple drivers, and (b) like #StrayPointer notices, you're using blocking assignments for assigning Register (Flip-Flop) values.
I'm guessing your intent was the following, which could fix a lot of simulation mismatches:
module testcounter
(
input wire clk,
input wire resetn,
input wire [31:0] num_to_count,
output reg [7:0] output_signal
);
reg [31:0] counter;
always#(posedge clk or negedge resetn) begin
if (!resetn) begin
counter <= 0;
end else begin
if (counter == num_to_count) begin
counter <= 0;
end else begin
counter <= counter + 1;
end
end
end
assign output_signal = (counter == num_to_count) ? 8'hff : 8'h00;
endmodule

Resources