How to create positive edge detector behavioural code? - verilog

I'm currently trying to code a positive edge detector that changes its output every time a positive edge is detected. I succeeded in building one with gate-level modelling, but now I need to build it using behavioral modelling. I tried building it using this foundation:
module pos_edge_det ( input sig,
input clk,
output pe);
reg sig_dly;
always # (posedge clk) begin
sig_dly <= sig;
end
assign pe = sig & ~sig_dly;
endmodule
I tried making code where in every positive edge it detects on the input, the output will always invert:
module posedgedet(in, out, clk, res);
input wire in,clk,res;
output wire out;
always # (posedge in, posedge clk)
begin
out <= ~out;
end
endmodule
When compiling, it returned this following error
Error: C:/Modeltech_pe_edu_10.4a/examples/pos edge detect.v(8): (vlog-2110) Illegal reference to net "out".
What does this error mean, and how do you properly use the always code to detect a positive edge on both input and clock pulse?

The error means that you can not declare out as a wire when you assign to it inside an always block. You need to declare out as a reg. I posted your module on edaplayground and compiled it on several simulators, one of which produced this slightly more specific error message:
out is declared here as wire.
At least that gives you a hint that there is something wrong with using wire.
There is also a problem with this line:
always # (posedge in, posedge clk)
That will not be synthesized into a flip-flop.
I think you are looking for a module which will detect a posedge on sig and generate an output pe which will be a single-clock wide pulse and also generate an output out which will toggle every time a posedge on sig is seen. I'm assuming your res signal is a reset. I also included a simple testbench.
module pos_edge_det (
input sig,
input clk,
input res,
output pe,
output reg out
);
reg sig_dly;
always # (posedge clk or posedge res) begin
if (res) begin
sig_dly <= 0;
end else begin
sig_dly <= sig;
end
end
assign pe = sig & ~sig_dly;
always # (posedge clk or posedge res) begin
if (res) begin
out <= 0;
end else if (pe) begin
out <= ~out;
end
end
endmodule
module tb;
reg clk, res, sig;
wire pe, out;
initial begin
clk = 0;
forever #5 clk =~clk;
end
pos_edge_det dut (
// Inputs:
.clk (clk),
.res (res),
.sig (sig),
// Outputs:
.out (out),
.pe (pe)
);
initial begin
sig = 0;
res = 1;
#20 res = 0;
repeat (10) #30 sig = ~sig;
#5 $finish;
end
endmodule

Related

why does my output signal have 2 clock cycles delay?

For each bit in a 32-bit vector, capture when the input signal changes from 1 in one clock cycle to 0 the next. "Capture" means that the output will remain 1 until the register is reset (synchronous reset).
Each output bit behaves like a SR flip-flop: The output bit should be set (to 1) the cycle after a 1 to 0 transition occurs. The output bit should be reset (to 0) at the positive clock edge when reset is high. If both of the above events occur at the same time, reset has precedence. In the last 4 cycles of the example waveform below, the 'reset' event occurs one cycle earlier than the 'set' event, so there is no conflict here.
In the example waveform below, reset, in1 and out1 are shown again separately for clarity.
my code:
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out );
integer i;
reg [31:0] in_del;
reg [31:0] out_del;
always # (posedge clk)
begin
in_del<=in;
out_del<=~in & in_del;
if (reset)
out=0;
else
begin
for (i=0; i<32;i=i+1) begin
if (out_del[i])
out[i]=out_del[i];
end
end
end
endmodule
my output
First about your code.
it cannot be compiled. The out must be a reg in order to be assignable within the always block.
using non-blocking assignment in out_del <= in & in_del will cause a one-cycle delay for the if (out_del) comparison. Non-blocking assignments schedule lhs assignment after the block gets evaluated. The rule of thumb is to always use blocking assignments for intermediate signals in the sequential block.
because of the above and because of the in & in_del, this cannot be synthesized, or at least it cannot be synthesized correctly.
you violate industry practices by using the blocking assignment on the out signal. The rule of thumb is to always use non-blocking assignments for the outputs of the sequential blocks.
the code just does not work :-(
If I understood your requirement correctly the following code does it:
module top_module (
input clk,
input reset,
input [31:0] in,
output reg [31:0] out );
reg lock;
always # (posedge clk)
begin
if (reset) begin
lock <= 0;
out <= 0;
end
else if (lock == 0)
begin
out <= in;
lock <= 1;
end
end
endmodule
Just use the lock signal to allow updated. And yes, here is a simple test bench to check it:
module real_top();
reg clk, reset;
reg [31:0] in;
reg [31:0] out;
top_module tm(clk, reset, in, out);
initial begin
clk = 0;
forever #5 clk = ~clk;
end
integer i;
initial begin
in = 0;
reset = 1;
#7 reset = 0;
for (i = 1; i < 5; i++) begin
#10 in = i;
#10 reset = 1;
#10 reset = 0;
end
$finish;
end
initial
$monitor(clk, reset, in, out);
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

why output of a module can't reach from outside module

I write two module by Verilog.
first module is 4 bit counter:
module ASYNCHRONOUS_COUNTER( clk, res, out);
input clk;
input res;
output[3:0] out;
reg[3:0] out;
wire clk;
wire res;
initial
out = 4'b0;
always #(negedge clk or posedge res)
if(res) begin
out[0] <= 1'b0;
end else begin
out[0] <= ~out[0];
end
always #(negedge out[0] or posedge res)
if(res) begin
out[1] <= 1'b0;
end else begin
out[1] <= ~out[1];
end
always #(negedge out[1] or posedge res)
if(res) begin
out[2] <= 1'b0;
end else begin
out[2] <= ~out[2];
end
always #(negedge out[2] or posedge res)
if(res) begin
out[3] <= 1'b0;
end else begin
out[3] <= ~out[3];
end
endmodule
second module use first module :
module tripleInputClk(clk,tripledClk);
input clk;
wire clk;
output tripledClk;
wire tripledClk;
wire res;
wire[3:0] out;
reg temp;
initial
temp <= 1'b0;
//assign out = 3'b0;
assign res = ~out[3] & ~out[2] & out[1] & out[0];
ASYNCHRONOUS_COUNTER myCounter(
.clk(clk),
.res(res),
.out(out)
);
always #(posedge res)
begin
temp <= ~temp;
end
assign tripledClk = temp;
endmodule
first module works correctly, but when I compiled it and made it's wave form ,I understood that outputs of first module doesn't pass correctly and value of 'res' always equal '0'.
Here, res is declared as wire in your tripleInputClk module.
I simulated your code and observed that the signal tripledClk goes HIGH after three clock pulses. Thereby, suspecting that a posedge of res signal must occur. But, res is in continuous assignment statement. As soon as res becomes HIGH, the reg out changes (#(posedge res)) and again makes res LOW; all this in a single time stamp. So you are not able to view transition of res signal.
Also, after that, the tripledClk signal does not toggle as expected, I guess.
One way out is to declare res as reg in tripleInputClk module and remove it from continuous assignment. Instead, make it work on the edge of clock signal only.
This is because, reg is used to store values. Here, there is a circular dependency of res on out and vice-versa (i.e. out is also dependent on res). Henceforth, it creates some sort of confusing conditions(I would not term it as a race around condition exactly).
When you'll proceed to synthesis (even though initial block is not synthesizable here..!), the tool may issue this circular dependency warning. And, proper hardware may not be formed.
I've modified your code and provided a testbench to it. The only change is the one that I described here, i.e. res signal. Kindly go through the link below. The tripledClk is now also working fine as (3*frequency_of_clk).
Link to EDAPlayground.

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