# Verilog code question - basic circuit

Posted by Floydian on Sun, 06 Mar 2022 07:39:45 +0100

# Basic circuit

## 1-bit full adder

```module full_adder(
input a,
input b,
input cin,

output sum,
output cout
);
assign {cout,sum}=a+b+cin;
endmoudle
```
abcinsumcout
00000
00110
01010
01101
10010
10101
11001
11111
```module full_adder(
input a,
input b,
input cin,

output sum,
output cout
);
assign sum=a^b^cin;
assign cout=(a&b)
|(cin&b)
|(cin&b);
endmoudle
```

## 4-bit full adder

```module four_full_adder(
input [3:0] a;
input [3:0] b,
input cin,

output [3:0] sum,
output cout
);
assign {cout,sum}=a+b+cin;
endmoudle
```

## 4-1 multiplexer

```module four_mux(
input [3:0] a,
input [3:0] b,
input [3:0] c,
input [3:0] d,
input [1:0] sel,

output [3:0] mux_out
);
always@(*)
begin
case(sel)
2'b00:mux_out=a;
2'b01:mux_out=b;
2'b10:mux_out=c;
2'b11:mux_out=d;
endcase
end
endmodule
```

## Frequency divider

### Odd frequency divider

Odd frequency division by clock phase or

```module any_odd_div(
input clk,
input rst_n,

output div_clk
);

parameter odd = 5;
reg [3:0] cnt1 , cnt2;
reg clk_tem_pos , clk_tem_neg;

always @ (posedge clk or negedge rst_n)
begin
if (!rst_n) begin
cnt1 <= 4'b00;
clk_tem_pos <= 1'b0;
end
else begin
cnt1 <= (cnt1  == odd-1)?4'b0:cnt1+1'b1;
clk_tem_pos <= (cnt1< (odd-1)/2)?1'b1:1'b0;
end
end

always @ (negedge clk or negedge rst_n)
begin
if (!rst_n) begin
cnt2 <= 4'b00;
clk_tem_neg <= 1'b0;
end
else begin
cnt2 <= (cnt2  == odd-1)?4'b0:cnt2+1'b1;
clk_tem_neg <= (cnt2< (odd-1)/2)?1'b1:1'b0;
end
end

assign div_clk = clk_tem_pos|clk_tem_neg;
endmodule

```

Simulation:

````timescale 1ns / 1ps
module any_odd_div_tb( );
reg clk;
reg rst;
//reg clk_out;//concurrent assignment to a non-net 'clk_out' is not permitted
wire clk_out;

initial
begin
clk=0;
rst=0;
#50;
rst=1;
end

always
begin
#5
clk=~clk;
end

any_odd_div u1(.clk(clk),.rst_n(rst),.div_clk(clk_out));

endmodule
``` ## edge detection

Detect the edge of the input signal. When it is detected that the signal is from low to high, the corresponding signal output is high.

```module edge_detection(
input x,
input clk,
output y_pos,y_neg);

reg x_fron;
always@(posedge clk)
begin
x_fron<=x;
end

assign y_pos=~x_fron&x;//posedge
assign y_neg=x_fron&~x;//nededge
endmodule
```

simulation

```    module edge_dec_tb();

reg clk;
reg x_in;

wire y_pos,y_neg;

initial
begin
clk=0;
x_in=0;
#40
x_in=1;
#40
x_in=0;
end

always #5 clk=~clk;

edge_detection u2(.x(x_in),.clk(clk),.y_pos(y_pos),.y_neg(y_neg));

endmodule
```

## Sequence detection

The title comes from the Internet
Sequence detection: it is required to detect "10010" in the input code stream, and if it is detected, data_out output 1,. At the same time, overlap detection needs to be excluded, for example:
Input: 1-0-0-1-0_0-1-0-0-1-0-XXXXX
Output: 0-0-0-0-1_0-0-1-0-0-1-XXXXX
The second 1 in the output stream is the overlapping output, which needs to be excluded.

Two stage state machine:
There are two always block s that separate sequential logic from combinatorial logic. The current state and the next state are switched in the sequential logic, and the combinational logic realizes each input, output and state judgment.

Three stage state machine:
coding style:cur_state and next_state;
There are three always block s. One timing logic uses synchronous timing to describe the state transition, one uses combinatorial logic to judge the state transition conditions and describe the state transition law, and the third module uses synchronous timing to describe the output of each state. The output of sequential logic solves the burr problem of two-stage combinational logic.

A brief summary is:
**Moore state machine: * * the last state is the completed state.
**Mealy state machine: * * there is one less state than Moore state machine, and the last state judges the output at the same time.

Three stage state machine:
Write cur in the first section of temporal logic_ State and next_ Transfer relationship between states
In the second paragraph, write case, the conditions for each state to change to the next state
Third segment write output
Two stage state machine:
The first paragraph is the same as above
The second segment writes state transfer and output at the same time.

### Two stage state machine

Different from the three-stage formula, out needs to be reg type

````timescale 1ns / 1ps

module seq_dec(
input seq_in,
input clk,
input rst_n,
//procedural assignment to a non-register test_out is not permitted
output reg test_out);

//Define six states
parameter 	IDLE        = 6'b000001,
fir_1       = 6'b000010,
sec_10      = 6'b000100,
thir_100    = 6'b001000,
fou_1001    = 6'b010000,
out_10010   = 6'b100000;

reg [5:0] cur_state;
reg [5:0] next_state;

always@(posedge clk or negedge rst_n)
if (!rst_n) begin
//test_ out <= 1'b0; Duplicate definition
cur_state  <= IDLE;
//next_ state <= IDLE;// Multiple definitions
end
else begin
cur_state <= next_state;
end

always@(*)
begin
case(cur_state)
IDLE        :begin
next_state = (seq_in)? fir_1    : IDLE;
test_out=1'b0;
end
fir_1       :begin
next_state = (seq_in)? fir_1    : sec_10;
test_out=1'b0;
end
sec_10      :begin
next_state = (seq_in)? fir_1    : thir_100;
test_out=1'b0;
end
thir_100    :begin
next_state = (seq_in)? fou_1001 : IDLE;
test_out=1'b0;
end
fou_1001    :begin
next_state = (seq_in)? fir_1    : out_10010;
test_out=1'b0;
end
out_10010   :begin
next_state = (seq_in)? fir_1    : IDLE ;
test_out=1'b1;
end
default     :begin
next_state = IDLE ;
test_out=1'b0;
end
endcase
end

endmodule

```

### Three stage state machine

```module seq_dec(
input seq_in,
input clk,
input rst_n,
output test_out);

//Define six states
parameter 	IDLE        = 6'b000001,
fir_1       = 6'b000010,
sec_10      = 6'b000100,
thir_100    = 6'b001000,
fou_1001    = 6'b010000,
out_10010   = 6'b100000;

reg [5:0] cur_state;
reg [5:0] next_state;

always@(posedge clk or negedge rst_n)
if (!rst_n) begin
//test_ out <= 1'b0; Duplicate definition
cur_state  <= IDLE;
//next_ state <= IDLE;// Multiple definitions
end
else begin
cur_state <= next_state;
end

always@(*)
begin
case(cur_state)
IDLE        :next_state = (seq_in)? fir_1    : IDLE;
fir_1       :next_state = (seq_in)? fir_1    : sec_10;
sec_10      :next_state = (seq_in)? fir_1    : thir_100;
thir_100    :next_state = (seq_in)? fou_1001 : IDLE;
fou_1001    :next_state = (seq_in)? fir_1    : out_10010;
out_10010   :next_state = (seq_in)? fir_1    : IDLE ;
default     :next_state = IDLE ;
endcase
end

assign test_out=(cur_state == out_10010)?1'b1:1'b0;

endmodule
``` Testbench

````timescale 1ns / 1ps

module seq_dec_tb( );

reg seq_in;
reg clk;
reg rst_n;

wire test_out;

initial
begin
clk=0;
seq_in=0;
rst_n=0;
#5
seq_in=1;
rst_n=1;//Don't forget to pull up the reset signal
#10
seq_in=0;
#10
seq_in=0;
#10
seq_in=0;
#10
seq_in=1;
#10
seq_in=0;
#10
seq_in=0;
#10
seq_in=1;
#10
seq_in=0;
#10
seq_in=0;
#10
seq_in=1;
end

always #5 clk=~clk;

seq_dec u1(.seq_in(seq_in),.clk(clk),.rst_n(rst_n),.test_out(test_out));

reg [127:0] next_state_name;

always@(*) begin
case(u1.cur_state)//Directly use the name of the module instantiation
6'b000001:   next_state_name= "IDLE"   ;
6'b000010:   next_state_name= "fir_1";
6'b000100:   next_state_name= "sec_10";
6'b001000:   next_state_name= "thir_100";
6'b010000:   next_state_name= "four_1001";
6'b100000:   next_state_name= "out_10010";
default  :   next_state_name= "IDLE"  ;
endcase
end
endmodule

```

### Shift register method

````timescale 1ns / 1ps

//Use the register to save the value of each entry sequence. When the total length is 10010, the output is 1
//At the same time, clear the value of reg when the sequence is 10010 to avoid overlapping output

module seq_dec(
input seq_in,
input clk,
input rst_n,
output test_out);

reg [4:0] ud_test;

always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
ud_test<=5'b0;
else
ud_test<=(ud_test==5'b10010)?{4'b0,seq_in}:{ud_test[3:0],seq_in};
end

assign test_out=(ud_test==5'b10010)?1'b1:1'b0;

endmodule
```

## four × 4 look up table multiplier

The core of look-up table method is to store all possible results of multiplication, and then combine the two multiplied data as an address to directly find the corresponding results.
Implementation of 4-bit Multiplier: call 2-bit multiplier, that is, decompose the high-order wide data into low-order wide data, and then call the look-up table multiplier.

For 2N bit data a, it can be decomposed into A=A1 × 2 ^ n + A0, A1 is the high N bit and A0 is the low N bit
For 2-bit multipliers, A = 2 × A1 + A0，B = 2 × B1 + B0;
Multiplication expansion: a × B = 4 × A1 × B1 + 2 × A1 × B0 + 2 × A0 × B1 + A0 × B0;
For 4-bit multipliers, A = 4 × A1+ A0 ，B = 4 × B1 + B0;
Multiplication expansion: a × B = 16 × A1 × B1 + 4 × A1 × B0 + 4 × A0 × B1 + A0 × B0;  ````timescale 1ns / 1ns

module inst(
input rst_n,
input [3:0] a,
input [3:0] b,
output  wire [7:0] mul4
);
//A×B = 16×A1×B1 + 4×A1×B0 + 4×A0×B1 + A0×B0
//reg [3:0] a1b1;concurrent assignment to a non-net
wire [3:0] a1b1;
wire [3:0] a1b0;
wire [3:0] a0b1;
wire [3:0] a0b0;

//Materialization
MULT2x2 u1(.rst_n(rst_n),.a(a[3:2]),.b(b[3:2]),.mul(a1b1));
MULT2x2 u2(.rst_n(rst_n),.a(a[3:2]),.b(b[1:0]),.mul(a1b0));
MULT2x2 u3(.rst_n(rst_n),.a(a[1:0]),.b(b[3:2]),.mul(a0b1));
MULT2x2 u4(.rst_n(rst_n),.a(a[1:0]),.b(b[1:0]),.mul(a0b0));

//assign mul4 = (!rst_n)? 8'b0:{a1b1,4'b0}+{a1b0,3'b0}+{a0b1,3'b0}+a0b0;
assign mul4 = (!rst_n)? 8'b0:{a1b1,4'b0}+{a1b0,2'b0}+{a0b1,2'b0}+a0b0;

endmodule

module MULT2x2(
input rst_n,
input [1:0] a,//A = 2×A1 + A0
input [1:0] b,//B = 2×B1 + B0
output reg[3:0] mul
);

always @(*) begin
if (!rst_n)
mul=4'd0;
else begin
case({a,b})//Don't follow begin after case
4'b0000:mul=4'd0;
4'b0001:mul=4'd0;
4'b0010:mul=4'd0;
4'b0011:mul=4'd0;
4'b0100:mul=4'd0;
4'b0101:mul=4'd1;
4'b0110:mul=4'd2;
4'b0111:mul=4'd3;
4'b1000:mul=4'd0;
4'b1001:mul=4'd2;
4'b1010:mul=4'd4;
4'b1011:mul=4'd6;
4'b1100:mul=4'd0;
4'b1101:mul=4'd3;
4'b1110:mul=4'd6;
4'b1111:mul=4'd9;
endcase
end
end

endmodule

```

testbench

````timescale 1ns / 1ns

module inst_tb();

reg [3:0]a;
reg [3:0]b;
reg rst_n;
wire [7:0] mul;

initial
begin
#5
rst_n=0;
#5
rst_n=1;
a=4'd2;
b=4'd3;
#5
a=4'd10;
b=4'd3;
#5
a=4'd9;
b=4'd3;
#5
a=4'd2;
b=4'd6;
#5
a=4'd2;
b=4'd4;
#5
a=4'd2;
b=4'd7;
#5
a=4'd2;
b=4'd5;
#5
a=4'd5;
b=4'd3;
end

inst zpz1 (.rst_n(rst_n),.a(a),.b(b),.mul4(mul));

endmodule
``` ## 64bits is detected as the lowest bit of 1

```module low_bit_dec(
input [63:0] data,
output reg [5:0] out_nm
);
integer i;
always @(*)
begin
for (i=0; i < 63 ; i=i+1)
if (data[i] == 1'b1)
out_nm = i;
else
//wrong: out_nm= 6'bx;
out_nm= out_nm;
end

endmodule
```

## Multiply two 8-digit numbers

Using a cycle, each of a number and its corresponding number are added with the subsequent phase shift.

````timescale 1ns / 1ns
//
// Company:
// Engineer:
//
// Create Date: 2022/02/24 18:47:02
// Design Name:
// Module Name: inst
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
//
//

module inst(
input [7:0] data1,
input [7:0] data2,
input       rst_n,
output [15:0] mul_ans
);

reg [15:0] mid_ans;
reg [15:0]
reg [7:0] low_ans;

integer i;
always @(*) begin
if(!rst_n) begin
mid_ans=16'b0;
low_ans=8'b0;
end
else begin
for (i=1; i < 8 ; i=i+1)
mid_ans=(data1[i])? (mid_ans + (data2 << i)):mid_ans;
low_ans={8{data1}}&data2;
end
end

assign mul_ans=mid_ans+low_ans;

endmodule

``` The result is incorrect. Error reason: the value of each time is not cleared, including the previous value, i.e. 182 + 32 * 13 = 598

Change:

````timescale 1ns / 1ns

module  8x8mul(
input [7:0] data1,
input [7:0] data2,
input       rst_n,
output [15:0] mul_ans
);

reg [15:0] mid_ans;
wire [15:0] ap_data2;
reg [7:0] low_ans;

assign ap_data2=data2;

integer i;
always @(*) begin
mid_ans=16'b0;//There is no error in multiple assignments in the same block
if(!rst_n) begin
mid_ans=16'b0;
low_ans=8'b0;
end
else begin
for (i=1; i < 8 ; i=i+1)
mid_ans=(data1[i])? (mid_ans + (ap_data2 << i)):mid_ans;
low_ans={8{data1}}&data2;
end
end

assign mul_ans=mid_ans+low_ans;

endmodule
```

## Decimal counter

```module 10counter(
input clk,
input rst_n,
output reg [3:0] ctr
);

always @(posedge clk) begin
if (!rst_n)
ctr=4'b0;
else
ctr=((ctr+1'b1)==4'b1010)?4'b0:ctr+1'b1;
end
endmodule
```

## DFF description

```module DFF(
input clk,
input rst_n,
input d,

output reg q
);
always @(posedge clk) begin
if (!rst_n)
q<=1'b0;
else
q<=d;
end

endmodule
```

## Comparison circuit - retain maximum

```module comparator(
input clk,
input rst_n,
input [7:0] a,
input [7:0] b,

output reg [1:0] q
);
always @(*) begin
if (a > b)
q <= 2'b01;
else if (a == b)
q <= 2'b00;
else
q <= 2'b10;
end

endmodule
```

## Single hot code detection

Given A 4-bit signal A, design logic to judge whether A is A single hot code and set the output as Y. if A is A single hot code, Y outputs 1; if not, 0
The idea is to sum the digits

```module one_hot(
input clk,
input rst_n,
input [3:0] a,

output reg  q
);
always @(*) beginone_hot
if ((a+a+a+a) == 1)
q <= 1'b1;//one hot bit
else
q <= 1'b0;
end

endmodule

```

## Settable hex cycle counter

```module load_cnt(

input clk,
input rst_n,
output reg [2:0] out
);
parameter load_N = 2;

always @(posedge clk) begin
if (!rst_n)
out='b0;
else
out = ((out+1'b1)==7)?'b0:out+'b1;
end

endmodule
```

## Parity bit Parity bit is a binary number that represents a given location number. The number of 1 is an odd or even binary number. Parity bit is the simplest error detection code.
Bitwise XOR: even check
Bitwise XOR Negation: odd check

## Deburring

Causes of burrs
When the signal passes through the wiring and logic gate inside the FPGA device, there is generally a certain delay. The size of the delay is related to the length of the connection and the number of gate units. At the same time, it is also affected by the manufacturing process, working voltage, temperature and other conditions of the device. In addition, the high / low level conversion of the signal also needs a certain transition time. Due to the influence of these factors, when the level value of multi-channel signal changes, at the moment of signal change, the output of combinational logic has sequence, rather than changing at the same time, which often leads to some incorrect "burrs".
There are two types of circuits for "burr" signals. The first is the asynchronous circuit with different delay after the input signal is wired inside the FPGA; The second is because the internal signal changes backward during programming. When multiple signals are correlated, if the first signal changes backward, the subsequent signals will produce uncertainty, resulting in "burr". The existence of "burr" indicates that the circuit is unstable, so it is likely to lead to the misoperation of the whole system.

terms of settlement:
Combinational logic circuit: add synchronous clock in the circuit, that is, input and output plus trigger to make the output signal change synchronously with the clock.
The discriminant assignment of the internal signal in the program does not change immediately, but there is a delay. This is also the most likely situation to produce "burr": the method of adding trigger is used to eliminate "burr"

## Serial parallel conversion

```module inst(

input clk,
input rst_n,
input a,
output reg [7:0] b
);

always @(posedge clk) begin
if (!rst_n)
b='b0;
else
b = {b[6:0],a};
end

endmodule
```

## Key shaking elimination 15ms

When the mechanical key is pressed and bounced, it will shake for a short time, and the shaking time generally lasts for 15ms.
In the design with few keys, the keys are often reused. The common method is to judge according to the length and short of key pressing time. Therefore, key reuse often uses the falling edge after key debounce (if the key is pressed with high potential).

Assume key is key_in, set a sampling register sw_rst records the value of the last clock
Judgment key_ Whether in is consistent with the value of the previous register. If it is inconsistent, it indicates that the key action may occur (detection of rising and falling edges), and the key action is registered in edge_en，edge_n = 1 indicates the action of generating the key
Then start the 15ms counter to count. After 15ms delay, set the key_ Assign in value to out

```module key (
input clk,
input rst_n,
input key_in,
output reg sw_out
);
reg sw_rst;//The key itself is 1, and it is 0 after being pressed

always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
sw_rst <= 1'b1;
end
else begin
sw_rst <= key_in;
end
end

wire pos_ed,neg_ed;
assign pos_ed = !sw_rst & key_in;//Rising edge
assign neg_ed = sw_rst & !key_in; //Falling edge

wire edge_en;
assign edge_en = pos_ed | neg_ed; //Check whether the key value changes (rising edge and falling edge)

reg [19:0] cout ;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
count <= 0;
end
else if(edge_en) begin
count <= 0;
end
else begin
count <= count + 1;
end

end

always @(posedge clk or negedge rst_n) begin
if (!rst_n)
sw_out <= 1'b1;
else
sw_out <= key_in;
end

endmodule
```

Topics: Verilog FPGA