The following is a snippet from a code I wrote in verilog for XST. The log is full of errors. How do I correct the code? How and where do I use always#() and #() blocks? Where do I use blocking and non blocking assignments?
input wire CLOCK;
input wire [31:0] OUT_SQRT;
output wire [31:0] IN_SQRT;
input wire [31:0] RANDP;
integer randp;
integer flagp;
integer sqrootp;
integer check_primep;
always #(posedge CLOCK and flagp != 0)
begin
#10
#(posedge and flagp != 0 )
begin
flagp = sqrootp%check_primep;
if(flagp != 0 and check_primep < sqrootp)
begin
check_primep = check_primep + 1;
end
#(posedge and flagp == 0)
begin
flagp = 1;
check_primep = 2;
randp = RANDP;
#5
IN_SQRT = randp;
#10
sqrootp = OUT_SQRT;
end
end
A flip-flop is implied using:
always #(posedge clk) begin
flip_flop_q <= flip_flop_d;
end
To make some thing synchronously (sampled on the clock) enabled:
always #(posedge clk) begin
if (flagp != 0) begin
flip_flop_q <= flip_flop_d;
end
end
Combinatorial logic is implied using:
always #* begin
comb_logic = a + b;
end
Things like the following (delays) are not synthesizable:
#10
#(posedge and flagp != 0 ) // no always just a delay waiting for criteria
Often used in test harnesses to wait for signals like resets etc being released.
initial begin
#(posedge reset_n);
#(posedge clk);
#(posedge clk);
//begin test procedure
end
If you need to wait for a signal in synthesisable verilog you need to build a FSM (Finite State Machine) to sequence your logic.
Related
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
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.
How to create a simple one stage pipeline in Verilog?
The easiest way to create a single state pipeline is create two always block synchronized with piped input(in_pipe) as given below. This work because of how the events are queued in the simulator time cycle.
module pipeline (reset,in,clock,out)
input reset, input, clock;
output out;`
logic reset, input, clock;
reg out, in_pipe;
always #(posedge clock or negedge reset)
begin
if(reset)
begin
in_pipe <= 0;
end
else
begin
in_pipe <= in;
end
end
always #(posedge clock or negedge reset)
begin
if(reset)
begin
out<= 0;
end
else
begin
out<= in_pipe;
end
end
module pipeline#(
parameter PIPE_NUM = 2,
parameter DATA_WIDTH = 32
)(
input clock,
input [DATA_WIDTH-1:0]data_in,
output [DATA_WIDTH-1:0]data_out
);
//synthesis translate_off
initial begin
if(PIPE_NUM < 1) begin
$fatal("Error: PIPE_NUM must be greater than 0!");
end
end
//synthesis translate_on
reg [DATA_WIDTH-1:0]pipeline_reg[PIPE_NUM-1:0]/*synthesis preserve*/;
assign data_out = pipeline_reg[PIPE_NUM-1];
integer p;
always #(posedge clock)begin
pipeline_reg[0] <= data_in;
for(p = 1;p < PIPE_NUM;p = p+1)begin
pipeline_reg[p] <= pipeline_reg[p-1];
end
end
endmodule
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.
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