Debouncer in Verilog - verilog

I'm trying to implement this debouncer circuit in Verilog. This is the code I got, and I believe it should work, but it doesn't. The problem is that the button_debounce signal is always 0.
module divider(clk, reset, divded_clock_out);
input clk;
input reset;
output reg divded_clock_out;
reg [19:0]counter;
always #(posedge clk or negedge reset)
begin
if(!reset)
counter <= 0;
else
begin
if (counter == 999999)
counter <= 0;
else
counter <= counter + 1;
if (counter < 499999)
divded_clock_out <= 0;
else
divded_clock_out <= 1;
end
end
endmodule
module dff(clk, D, Q, reset);
input clk;
input reset;
input D;
output reg Q;
always # (posedge clk or posedge reset)
begin
if(reset)
Q <= 1'b0;
else
Q <= D;
end
endmodule
module debounce(clk, button, button_debounce, reset);
input clk;
input reset;
input button;
output button_debounce;
wire [2:0]reg_wire;
dff reg1(clk, button, reg_wire[0], reset);
dff reg2(clk, reg_wire[0], reg_wire[1], reset);
dff reg3(clk, reg_wire[1], reg_wire[2], reset);
assign button_debounce = reg_wire[0] & reg_wire[1] & reg_wire[2];
endmodule
module debouncer_tb();
reg clk;
reg reset;
reg button;
wire divded_clock_out;
wire button_debounce;
initial begin
clk = 0;
reset = 0;
button = 0;
#10;
reset = 1;
button = 1;
end
always #10 clk=~clk;
divider uut(clk, reset, divded_clock_out);
debounce uut2(divded_clock_out, button, button_debounce);
endmodule
The divider works as expected, and I believe it's only a problem with the debouncer module. For the simulation testbench, the output of the divider is correct and the output of the debouncer is always 0, and it should be 1 when the button input changes to 1.

When I run a simulation, I get the following compile warning:
debounce uut2(divded_clock_out, button, button_debounce);
|
xmelab: *W,CUVWSI : 1 input port was not connected:
xmelab: reset
The debounce module has 4 ports, but you only connected 3 of them. Check your log files to see if you have a similar message.
Also, when I run the simulation, I see button_debounce as X (unknown), not 0.
When I change:
debounce uut2(divded_clock_out, button, button_debounce);
to:
debounce uut2(divded_clock_out, button, button_debounce, ~reset);
I see button_debounce go to 1, as desired. I added reset to the connection list. Note that I inverted the reset signal because your dff modules use an active-high reset, whereas the divider uses an active-low reset.
However, using connection-by-order, as shown above, is error prone. It is better to use connection-by-name:
debounce uut2 (
.clk (divded_clock_out),
.button (button),
.button_debounce (button_debounce),
.reset (~reset)
);

Related

How to get my one-shot to toggle its output (SystemVerilog)

I've been designing a one-shot as part of my EE senior project and am unable to get the 'Reset' to toggle the output to 0.
I used the RTL_viewer in Quartus and the design does match my code: The DFF output (Q) is fed into 2 inverters then into the DFF Reset.
My understanding is that the two inverters should act as buffers. The DFF output should be 0 until the next clock edge is reached. I'm not sure if something is wrong with my design or if this is a timing error. I tried playing around with the clock speed and the buffer delay, but neither produced the correct results.
module oneShot(Clk, Q, Q_bar);
input Clk;
output Q, Q_bar;
logic X, Reset /* synthesis keep */;
logic D = 1'b1;
parameter propogation_delay = 30ns;
not #(propogation_delay) (X, Q);
not #(propogation_delay) (Reset, X);
//instantiation of flip flop
//DFF (Clk, Reset, D, Q);
DFF1 unit0 (Clk, Reset, D, Q);
assign Q_bar = ~ Q;
endmodule
module DFF1 (Clk, Reset, D, Q);
input Clk, Reset, D;
output logic Q;
always_ff #(posedge Clk)
begin
if(Reset == 1'b1)
Q <= 0;
else
Q <= D;
end
endmodule
module oneShot_tb;
logic Clk, Q, Q_bar, Reset;
oneShot DUT (Clk, Q, Q_bar);
always begin
Clk = 0;
#10;
Clk = 1'b1;
#10;
end
initial begin
#300;
$stop;
end

Delay a 32-bit signal with N clock cycle in verilog

I am trying to delay a 32-bit signal using shift register. My logic is a single flip flop delay a signal by 1 clk so I use shift register as it is combination of flip flop can someone guide me what is wrong with this code.
module delay_n_cycles (
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out,
parameter N = 5
);
reg [31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= {shift_reg[30:0], data_in};
if (N == 0) begin
data_out <= shift_reg[31];
end else begin
data_out <= shift_reg[N-1];
end
end
endmodule
First of all, your code is syntactically wrong. parameter cannot be declared in a way you provided.
Your shift register is only 32 bit wide. Usually, to delay multi-bit data this way, you need to keep N copies of data in the register, shift them at one end and read at the other. I guess the following should help:
module delay_n_cycles #(parameter N = 5)(
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out
);
reg [N-1:0][31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= (shift_reg << 32) | data_in;
data_out <= shift_reg[N-1];
end
endmodule
This code will work with system verilog because it used packed multi-dimensional arrays.
You need to shift the reg by 32 (width of the data) in packed version.
Here is an example of a testbench:
module tb();
bit clk;
int clkCount;
initial
forever begin
#5 clk = ~clk;
clkCount++;
end
logic [31:0] data_in, data_out;
initial begin
$monitor("%0t (%0d) [%h]: %0d --> %0d", $time, clkCount, ds.shift_reg[4], data_in, ds.data_out);
for(int i = 0; i < 20; i++) begin
#10 data_in = i;
end
$finish;
end
delay_n_cycles ds(data_in, clk, data_out);
endmodule

No response from uut in testbench

I am not getting any response from the uut in the testbench. The module exp2_up_down_counter works ok without testbench, but gives output as xxxx when instantiated in the testbench.
Here is the main module of the up-down counter:
`timescale 1ns/1ps
module exp2_up_down_counter (input clk, reset, mode, output reg [3:0] count);
always #(posedge clk)
if (reset == 1)
count <= 0; // reset the counter if reset is high
else if (mode == 1)
count <= count + 1; // works as up counter if mode pin is high
else
count <= count - 1; // works as down counter if mode pin is low
endmodule
Simulation without testbench:
Testbench for up-down counter
`timescale 1ns/1ps
module exp2_up_down_counter_tb;
reg clk, reset, mode;
wire [3:0] count;
exp2_up_down_counter uut(.clk(clk), .reset(reset), .mode(mode), .count(count));
initial begin
clk = 1'b0;
end
always #(*) #5 clk <= ~clk;
initial begin
// initializing the inputs
reset = 1;
mode = 0;
#5;
reset = 0;
#10
mode = 1;
#5000 $finish;
end
endmodule
Simulation with testbench:
In exp2_up_down_counter, count is declared as a reg. This means that its default value is X at time 0. Since the reset signal is synchronous to the clock, you need to wait for the 1st posedge of clock before you release the reset. Currently, the reset is released at the 1st posedge of clock in the testbench, which is a race condition. Therefore, count does not get assigned the value of 0, and it retains the value of X for the whole simulation.
You need to delay the reset release. For example, change:
#5;
reset = 0;
to:
#15;
reset = 0;
However, it is better to drive your synchronous inputs in the testbench the same way you drive your signals in the design: using #(posedge clk) and using nonblocking assignments (<=):
initial begin
reset = 1;
mode = 0;
repeat (2) #(posedge clk);
reset <= 0;
repeat (1) #(posedge clk);
mode <= 1;
#5000 $finish;
end
Also, this is a more standard way to drive the clock in the testbench:
always #5 clk = ~clk;

Verilog: one clock cycle delay using register

I'm trying to delay two signals. I wrote a register to do that and instantiated it but a strange thing happens. Delaying "state" signal seems to work, but delaying "nb_bits" signal doesn't.
Here's my code for the register:
`timescale 1ns / 1ps
module register(
input CLK,
input clr,
input en,
input [7:0] in,
output [7:0] out
);
reg [7:0] temp;
always # (posedge CLK or posedge clr) begin
if (clr) begin
temp <= 8'b00010000;
end
else if (en) begin
temp <= in;
end
else begin
temp <= temp;
end
end
assign out = temp;
endmodule
And that's ma instantiation:
wire [3:0] nbb;
nb_bits_register nb_bits_reg(
.CLK(CLK),
.clr(clr),
.en(en),
.in(nb_bits),
.out(nbb)
);
wire [7:0] stt;
register state_reg(
.CLK(CLK),
.clr(clr),
.en(en),
.in(state),
.out(stt)
);
nb_bits_register module is analogical; I didn't want to parametrize before solving this problem.
`timescale 1ns / 1ps
module nb_bits_register(
input CLK,
input clr,
input en,
input [3:0] in,
output [3:0] out
);
reg [3:0] temp;
always # (posedge CLK or posedge clr) begin
if (clr) begin
temp <= 4'b0000;
end
else if (en) begin
temp <= in;
end
else begin
temp <= temp;
end
end
assign out = temp;
endmodule
And here's a simulation:
enter image description here
And testbench:
`timescale 1ns / 1ps
module state_machine_tb();
reg CLK, clr, en;
reg [7:0] symbol;
reg [3:0] nb_bits;
wire [7:0] state;
initial begin
CLK <= 1;
clr <= 0;
en <= 0;
symbol <= 8'b00110010;
nb_bits <= 1;
#10
clr <= 1;
en <= 1;
#10
clr <= 0;
symbol <= 8'b00110001;
nb_bits <= 1;
#10
symbol <= 8'b00110010;
nb_bits <= 2;
#10
symbol <= 8'b00110001;
nb_bits <= 1;
#10
symbol <= 8'b00110001;
nb_bits <= 1;
#10
symbol <= 8'b00110000;
nb_bits <= 3;
#10
$finish;
end
always begin
#5 CLK <= ~CLK;
end
state_machine state_machine_inst(
.CLK(CLK),
.clr(clr),
.en(en),
.symbol(symbol),
.nb_bits(nb_bits),
.state(state)
);
endmodule
It does seem like a rase condition in the scheduler. By definition from the Verilog LRM, the order of evaluating procedural blocks (always blocks and initial blocks) is indeterminate. You might notice a pattern with a particular simulator and version, but that patter can change when changing the simulator or changing the version of the same simulator.
Use blocking assignment with your clock (ex: always #5 CLK = ~CLK;). With will guarantee the CLK will be updated before other stimulus.
In the test bench, change all the #10 to #(posedge CLK). The timing will be the same, however it guarantees CLK was updated before evaluating the new values symbol and other stimulus.
FYI: If you change output [7:0] out to output reg [7:0] out you can assign out directly in your always block, removing the need for temp. This doesn't change anything functionally; just fewer variables and lines of code.
It seems like a race condition: your changes of nb_bits coincide with positive edges of CLK, so there's an ambiguity resolved by the simulator in this way:
change nb_bits (from 1 to 2, etc.)
change CLK from 0 to 1
execute in nb_bits_register: if (en) temp <= in; ... assign out = temp;
As the result, out = in in nb_bits_register.
A solution is to avoid this coincidence, e.g. by changing the first #10 in the testbench to #11.

Parse error when I try to use Verilog; testbenching an LFSR doesn't work

I am currently working on random number generation using Verilog. Sources have indicated that using Linear Feedback Shift Registers are one of the best ways to randomize MSBs. So I decided to code and testbench an LFSR. Snippet is below:
module lfsr_counter(clk, reset, ce, lfsr_done);
input clk, reset, ce;
output lfsr_done;
reg lfsr_done;
reg [10:0] lfsr;
initial lfsr_done = 0;
wire d0,lfsr_equal;
xnor(d0,lfsr[10],lfsr[8]);
assign lfsr_equal = (lfsr == 11'h359);
always #(posedge clk,posedge reset) begin
if(reset) begin
lfsr <= 0;
lfsr_done <= 0;
end
else begin
if(ce)
lfsr <= lfsr_equal ? 11'h0 : {lfsr[9:0],d0};
lfsr_done <= lfsr_equal;
end
end
endmodule
module testbench();
reg clk, reset, ce;
wire lfsr_done;
lfsr_counter dut(clk, reset, ce, lfsr_done); // Design Under Test
initial
begin
reset = 0;
clk = 1;
ce = 0;
#100
ce = 1;
#200 $finish;
end
//Generate Clock
always #10 clk = !clk;
endmodule
But I keep getting these parse errors:
I don't really get it. I'm using Verilogger Pro btw
I think always block terms are separated by or, not a comma.
always #(posedge clk or posedge reset) begin

Resources