Verilog deterministic behavior - verilog

Is following code deterministic? i.e Can it trigger error1 or error2? Is there a recommended way for generating clk2 (same as clk3)
module Test();
reg clk1;
reg clk2;
reg clk3;
reg reset;
initial
begin
clk1 <= 0;
forever
begin
#100;
clk1 <= ~clk1; // 2x freq of clk2/clk3
end
end
always #(posedge clk1)
begin
if(reset) clk2 <= 0;
else clk2 <= ~clk2;
end
initial
begin
clk3 <= 0;
#300;
forever
begin
#200;
clk3 <= ~clk3;
end
end
initial
begin
reset <= 1;
#500;
reset <= 0;
#100;
repeat (20) #(posedge clk1);
$display("Test end");
$finish;
end
always #(posedge clk2)
begin
if(clk1 == 0) $display("Error1");
end
always #(posedge clk3)
begin
if(clk1 == 0) $display("Error2");
end
endmodule;

Your code has problems, but nothing to do with determinism—it is fully deterministic. This is one case where using NBAs <= creates a problem. clk2 gets updated in a delta cycle after clk1 and clk3. That means if you have clock domain crossings from the latter to clk2 like
always_ff #(posedge clk3)
A <= B;
always_ff #(posedge clk2)
C <= A; // A has already been updated with the value of B
So never use NBAs to make assignments to clocks.

Related

Monostable multivibrator simulation

The monostable module implements a monostable multivibrator. It takes in three inputs (clk, reset, trigger) and outputs a single (pulse).
The trigger input triggers the module. When triggered, the output signal (pulse) will switch to a high position for a period of clock ticks, and then return to a low position. The pulse width of the output signal can be set via the PULSE_WIDTH parameter, which represents the period in clock ticks that the signal should stay high.
Now, what is happening is when it gets triggered, immediately output signal (pulse) is getting high.
When triggered, the output signal (pulse) should be high on the next active edge of clk. What changes can be done ?
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count = 0;
wire countReset = reset | (count == PULSE_WIDTH);
always #(posedge trigger, posedge countReset) begin
if (countReset) begin
pulse <= 1'b0;
end else begin
pulse <= 1'b1;
end
end
always #(posedge clk, posedge countReset) begin
if(countReset) begin
count <= 0;
end else begin
if(pulse) begin
count <= count + 1'b1;
end
end
end
endmodule
module monostable_tb();
reg clk;
reg reset;
reg trigger;
wire pulse;
parameter PULSE_WIDTH = 20;
monostable imonostable(.*);
initial begin
clk=0;
forever #50 clk=~clk;
end
initial begin
$monitor("trigger=%b pulse=%b, count = %0d",trigger,pulse,imonostable.count);
$dumpfile("monostable_tb.vcd");
$dumpvars(0,monostable_tb);
trigger=1'b0;
reset = 1'b0;
#(posedge clk) reset = 1'b1;
#(posedge clk) reset = 1'b0;
#(posedge clk) trigger=1'b1;
#(posedge clk) trigger=1'b0;
repeat(25) #(posedge clk);
$finish;
end
endmodule
Here is a simplified design which sets the output one cycle after the input trigger pulse, and keeps the output high for 20 cycles:
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count;
always #(posedge clk, posedge reset) begin
if (reset) begin
pulse <= 1'b0;
end else if (trigger) begin
pulse <= 1'b1;
end else if (count == PULSE_WIDTH-1) begin
pulse <= 1'b0;
end
end
always #(posedge clk, posedge reset) begin
if(reset) begin
count <= 0;
end else if (pulse) begin
count <= count + 1'b1;
end
end
endmodule
It now uses a single clock signal, instead of 2. It also uses a simple reset signal, which can avoid potential glitches causing unwanted asynchronous resets.
You should also use nonblocking assignments in the testbench:
#(posedge clk) reset <= 1'b1;
#(posedge clk) reset <= 1'b0;
#(posedge clk) trigger<= 1'b1;
#(posedge clk) trigger<= 1'b0;
If a 1-clock synchronous delay is needed, then run the output thru a flip flop.
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count = 0;
reg reg_pulse_temp;
wire countReset = reset | (count == PULSE_WIDTH);
always #(posedge trigger, posedge countReset) begin
if (countReset) begin
reg_pulse_temp <= 1'b0;
end else begin
reg_pulse_temp <= 1'b1;
end
end
always #(posedge clk, posedge countReset) begin
if(countReset) begin
count <= 0;
// reset the flop
pulse <= 0;
end else begin
if(pulse) begin
count <= count + 1'b1;
end
end
// flip flop
pulse <= reg_pulse_temp;
end
endmodule

How to start with zero counter verilog

I'm implementing a repeating bit shifter for a 16 bit number. To do this, I have a bit counter that counts how many times I've shifted and resets when I reach 4'b1111. Then I have an assign statement that feeds the MSB to an output. However, the logic makes it so that the output skips the first MSB every time. What is the most succinct way to include the first MSB, before any shifting has occurred?
CODE
module DAC_Control(
input [15:0]data_in,
input clk,
input rst,
output data_out,
output reg cs,
output reg enable
);
//bit counter
reg [3:0] bit_counter;
//to help with shifting
reg [15:0] shifter;
always #(data_in)
shifter <= data_in;
//shifter
always #(posedge (clk)) begin
if (rst) begin
bit_counter <= 4'b0;
enable <= 1'b0;
cs <= 1'b1;
end
else if (bit_counter == 4'b1111) begin
bit_counter <= 4'b0;
enable <= 1'b1;
cs <= 1'b1;
end
else begin //this is the problem area
bit_counter <= bit_counter + 1'b1;
enable <= 1'b0;
cs <= 1'b0;
shifter <= shifter << 1;
end
end
assign data_out = shifter[15];
endmodule
Firstly it would be better to have a trigger to capture the data_in. If not then in simulation ,if the data_in changes in between the shifting it will update the shifter and cause the expected output to change. It would be preferable to capture the data_in based on a qualifying event ( e.g. counter_enable in the example below) . Synthesis will produce an error as shifter has two drivers . One the continuous assignment shifter <= data_in; and other the shifting logic shifter <= shifter << 1;
Updated sample code should serialize the data.
module DAC_Control(
input [15:0]data_in,
input counter_enable,
input clk,
input rst,
output data_out,
output reg cs,
output reg enable
);
//bit counter
reg [3:0] bit_counter;
//to help with shifting
reg [15:0] shifter;
//shifter
always #(posedge (clk)) begin
if (rst) begin
bit_counter <= 4'b0;
shifter <= 0;
end
else if (counter_enable == 1) begin
shifter <= data_in;
bit_counter <= 4'b0;
end
else begin
shifter <= shifter << 1; // shifting
bit_counter <= bit_counter + 1'b1; // counter
end
end
always #(posedge (clk)) begin
if (rst) begin
enable <= 1'b0;
cs <= 1'b1;
end
else if (bit_counter == 4'b1111) begin
enable <= 1'b1;
cs <= 1'b1;
end
else begin
enable <= 1'b0; // generate enable signals
cs <= 1'b0;
end
end
assign data_out = shifter[15];
endmodule

How to create synthesizeable delay?

i got a code like below with clk = #10 ~clk
always# (posedge clk)begin
for (g=0;g<8;g=g+1) begin
ws = 1;
#20
ws = 0;
#20;
end
so is there any other way to make the delay 20 synthesizaeble in the coding above?
A flip-flop is the only way of synthesising a delay:
always #(posedge clk)
q <= d;
With clk = #10 ~clk;, q will be #10 later than d.
The question appear not to be how to synthesis a #20 but how to control the timing for signals in to a RAM. Digital design are based around clock edges, with each positive or negative edge a set distance a part, this is the period of the clock or 1/frequency.
To sequence events as you describe you need a FSM (Finite state machine) to control or sequence it. I have included a small example below:
Available on EDA Playground
module tb;
//Tb component
reg clk;
reg rst_n;
initial begin :clk_and_reset
clk = 0;
rst_n = 0;
#40 rst_n = 1;
#40;
forever begin
#20 clk = ~clk;
end
end
//Design
reg [1:0] state;
reg [1:0] next_state;
reg [31:0] counter;
reg ws;
localparam S_IDLE = 'd0;
localparam S_WAIT = 'd1;
localparam S_OFF = 'd2;
always #(posedge clk, negedge rst_n) begin
if (~rst_n) begin
state <= S_IDLE;
end
else begin
case(state)
S_IDLE : begin
state <= S_WAIT;
counter <= 'b0;
S_WAIT :
if (counter < 32'd10) begin
state <= S_WAIT; //Wait for 10 clock cycles
counter <= counter + 1;
end
else begin
state <= S_OFF;
counter <= 'b0;
end
S_OFF : state <= S_IDLE;
default : state <= S_IDLE; //IDLE
end
end
//Output decode based on state
always #* begin
//ws goes high when in Wait state
ws = (state == S_WAIT);
end
//Test program
initial begin
repeat (10) begin
#(posedge clk);
$display("%4t : State %b: ws :%b", $realtime, state, ws);
end
$finish();
end
endmodule
This could be expanded by staying in idle until triggered then by having counter and staying in wait for x number of clocks, x number of clocks in OFF before going back to idle and waiting to be triggered again.
Update
I have updated the code example to stay in the WAIT state for 10 clock cycles to demonstrate how to control the delay between transitions.

Implementing JK Flipflop in Verilog

I'm trying to implement simple JK Flipflop in Verilog (Modelsim). But I'm getting the following error
The generate if condition must be a constant expression.
Here is the code which I'm using
module jkfflop(J,K,clk,Q);
input J,K,clk;
output Q;
if(J==0 & K==1)
begin
assign Q = 0;
end
else if(J==1 & K==0)
begin
assign Q = 1;
end
else if(J==1 & K==1)
begin
assign Q = ~Q;
end
endmodule
Can someone help me
In Verilog RTL there is a formula or patten used to imply a flip-flop. for a Positive edge triggered flip-flop it is always #(posedge clock) for negative edge triggered flip-flops it would be always #(negedge clock).
An Example of positive edge triggered block.
reg [7:0] a;
always #(posedge clock) begin
a <= b;
end
Normally you want a reset as well, a Synchronous reset would be:
reg [7:0] a;
always #(posedge clock) begin
if ( reset == 1'b1 ) begin
a <= 'b0;
end
else begin
a <= b;
end
end
It is more common is ASIC design to require an active low Asynchronous :
reg [7:0] a;
always #(posedge clock, negedge reset_n) begin
if ( reset_n == 1'b0 ) begin
a <= 'b0;
end
else begin
a <= b;
end
end
Note that the asynchronous reset has reset in the sensitivity list this makes the block respond to changes in the signal.
The way you have used (reused) assign is incorrect.
Using the above info your module would become:
module jkfflop(
input J,
input K,
input clk,
output Q );
always #(posedge clk) begin
if(J==1'b0 && K==1'b1) begin
Q <= 'b0;
end
else if(J==1'b1 && K==1'b0) begin
Q <= 1'b1;
end
else if(J==1'b1 & K==1'b1) begin
Q <= ~Q;
end
end
endmodule
But could be written with a case statement:
always #(posedge clk) begin
case({J,K})
2'b0_0 : Q <= Q ;
2'b0_1 : Q <= 1'b0;
2'b1_0 : Q <= 1'b1;
2'b1_1 : Q <= ~Q ;
endcase
end

Verilog + FPGA: If statement for switch

This is my code to control a RC Servo Motor. The code basically turns the 50MHz frequency to 1KHz.
I am using one of the switches on the FPGA to control the motor. Until the switch is on, none of the program should run.
But that doesn't seem to be happening. I don't know what I'm doing wrong. It's probably a very silly mistake.
module servo(clk,rst,clk_out,switch);
input clk,rst,switch;
output reg clk_out;
reg [15:0] counter;
always #(posedge clk or posedge rst or posedge switch)
if (switch) begin
if(rst) begin
counter <=16'd0;
clk_out <= 1'b0;
end
else if(counter==16'd25000) begin
counter <=16'd0;
clk_out <= ~clk_out;
end
else begin
counter<=counter+1;
end
end
endmodule
Also I tried changing the duty cycle so the motor rotates faster, but this doesn't seem to be working.
module servo (clk,rst,clk_out,switch);
input clk,rst,switch;
output reg clk_out;
reg [15:0] counter;
always #(posedge clk or posedge rst)
if(rst)
begin
counter<=16'd0;
clk_out <= 1'b0;
end
else if (switch)
begin
if(counter==16'd12500)
begin
clk_out <= 1'b1;
counter<=counter+1;
end
else
if(counter==16'd50000)
begin
counter <= 16'd0;
clk_out <= 1'b0;
end
else
begin
counter<=counter+1;
end
end
endmodule
Here's my cut at it - I haven't simulated it, so beware!
module servo(clk,rst,clk_out,switch);
input clk,rst,switch;
output reg clk_out;
reg [15:0] counter;
// clocked blocks should only have the clock and maybe a reset
// in the sensitivity list
always #(posedge clk or posedge rst) begin
if(rst) begin
counter <=16'd0;
clk_out <= 1'b0;
end
else if (switch) begin // 'switch' used as an enable
if(counter==16'd25000) begin
counter <=16'd0;
clk_out <= ~clk_out;
end
else begin
counter<=counter+1;
end
end
else begin
counter <= 16'd0;
end
end
endmodule
First thing I did was to remove the entry for switch in the sensitivity list - for synchronous logic, there should only be a clock and maybe a reset here.
The reset clause for the logic should be first, so I moved the test for switch using it as an enable signal in the main body of the always block. The counter will only run now if switch is high.

Resources