29_ZYNQ7020 development board combinational logic timing logic (Verilog)

Introduction to Verilog basic module

1. Constant

Integer: binary B or B, octal o or O, decimal D or D, hexadecimal h or H.
X and z:X represents the indefinite value, Z represents the high resistance value, for example, the third indefinite value of 5'b00x11, and 3'b00z represents that the lowest point is the high resistance value.
Underline: used for data segmentation to improve readability, such as 8'b0000_ one thousand one hundred and eleven
Parameter parameterparameter is used to define constants to improve readability, writing and maintainability.
Definition: parameter width = 8 definition register reg[width-1:0]a; A register that defines an 8-bit width.
Called module

module rom
#(
	parameter depth  =15,
	parameter width = 8
)
(
	input [depth-1:0] addr,
	input [width-1:0]data,
	output result
);
endmodule

Top level call module

module top();
wire [31:0] addr;
wire [15:0] data;
wire result;
rom
#(
.depth(32),
.width(16)
)
r1
(
.addr(addr),
.data(data).
.result(result)
);
endmodule

Parameter can be used for data transfer between modules, but localparam is only used in this module and cannot be used for parameter transfer. Local is mostly used for the definition of state machines.

2. Variables

A variable is the amount by which a program can change its value
wire type variables, also known as network type variables, are used for the physical connection between structural entities, such as between doors. They cannot store values, and are assigned with the continuous assignment statement assign.

wire a;assigan a=b;

Connect the node of b to line a. The wire type variable of the connection between two entities.
reg type variables, also known as register variables, must be used in the always statement
reg[n-1:0]a; Represents a register with n-bit width, such as reg[7:0]a; Represents a register a that defines an 8-bit width. The following is the D trigger.

module top(d,clk,q);
input d;
input clk;
output reg q;
always@(posedge clk)
	begin
		q<=d;
	end
endmodule


Data selector, combinational circuit

module top(a,b,c,d,sel,Mux);
input	a;
input	b;
input	c;
input	d;
input	[1:0] sel;
output	reg Mux;
always @(sel or a or b or c or d)
begin
	case(sel)
		2'b00:Mux = a;
		2'b01:Mux = b;
		2'b10:Mux = c;
		2'b11:Mux = d;
	endcase
end
endmodule

3. Operator

(1) Arithmetic operators (+, -. *, /,%)
"/" division operator 7 / 3 = 2
'%' modulo operator 7%3 = 1
(2) Assignment operator (=, < =)
=Blocking assignment
< = non blocking assignment
Blocking assignment is to complete one assignment statement and then execute the next one, which can be understood as sequential execution.
Non blocking assignment can be understood as parallel execution, regardless of order.
code:

module top(din,a,b,c,clk);
input din;
input clk;
output reg a,b,c;
always @(posedge clk)
	begin
		a = din;
		b = a;
		c = b;
	end
endmodule

Incentive documents:

`timescale 1 ns/1 ns
module top_tb();
reg din;
reg clk;
wire a,b,c;
initial
	begin
	din = 0;
	clk = 0;
	forever
		begin
			#({$random}%100)
			din = ~din;
		end
	end
	always #10 clk = ~clk;
	top
	t0(.din(din),.a(a),.b(b),.c(c),.clk(clk));
endmodule

Need simulation

(3) Relational operators (>, <, > =, < =, = =,! =)
(4) Logical operators (& &, ||,!)

(5) Conditional operator (?)? 😃
(6) Bitwise operators (, |, ^, &, ^)
(7) Displacement operator (<, > >)
(8) Splice operator ({})
"{}" splicing operator, splicing multiple signals by bits, such as {a[3:0],b[1:0]} splicing the lower 4 bits of a and the lower 2 bits of b into 6-bit data.
{n{1 'b0}} indicates o splicing of N bits
For example: {8 {1'b0}} is expressed as 8'b0000_0000
{n{a[3:0]}} means splicing n a[3:0].

4. Combinational logic

1. And gate

module top(a,b,c);
input a;
input b;
input c;
assign c - a & b;
endmodule

2. Or door

module top(a,b,c);
input a;
input b;
input c;
assign c = a | b;
endmodule

3. Non gate

module top(a,b);
input a;
output b;
assign b = ~a;
endmodule

4. XOR gate

module top(a,b,c);
input a;
input b;
output c;
assign c = a ^ b;
endmodule

5. Comparator

module top(a,b,c);
input a;
input b;
output c;
assign c=>a > b;
endmodule

6. Semi heater
The half adder does not consider the carry from the low order, so it is called the half adder. sum represents the addition result, count represents the carry, and the truth table can be expressed as follows:

module top(a,b,sum,count);
input a;
input b;
output sum;
output count;

assign sum = a ^ b;
assign count = a & b;
endmodule 

simulation

7. Full adder
The full adder needs to add the carry signal cin from the low position. The truth table is as follows:

module top(cin,a,b,sum,count);
input cin;
input a;
input b;
output sum;
output count;

assign {count,sum} = a + b +cin;
endmodule

simulation

8. Multiplier
Multiplier representation is also very simple, using a*b

module top(a,b,c);
input [1:0]a;
input [1:0]b;
output [3:0]c;
assign c =a * b;
endmodule

9. Data selector
Through the selection signal, different input signals are selected and output to the output end. One of four data selectors is selected. sel[1:0] is the selection signal, a, B, C and D are the input signals, and Mux is the output signal.

code:

module top(a,b,c,d,sel,Mux);
input a;
input b;
input c;
input d;
input [1:0] sel;
output reg Mux;
always @(sel or a or b or c or d)
begin
	case(sel)
		2'b00:Mux = a;
		2'b01:Mux = b;
		2'b10:Mux = c;
		2'b11:Mux = d;
	endcase
end
endmodule

Decoder 10-3
3-8 decoder is a very common device. The truth table is as follows. Different results are obtained according to the values of A2, A1 and A0


code

module top(addr,decoder);
input [2:0] addr;
output reg [7:0] decoder;
always @ (addr)
begin
	case(addr)
		3'b000 : decoder = 8'b1111_1110;
		3'b001 : decoder = 8'b1111_1101;
		3'b010 : decoder = 8'b1111_1011;
		3'b011 : decoder = 8'b1111_0111;
		3'b100 : decoder = 8'b1110_1111;
		3'b101 : decoder = 8'b1101_1111;
		3'b110 : decoder = 8'b1011_1111;
		3'b111 : decoder = 8'b0111_1111;
end
endmodule

9.D trigger

The D flip-flop stores the output on the rising or falling edge of the clock, and the output is the same as the state of the output signal before the clock jump.

module top(d,clk,q);
input d;
input clk;
output reg q;
always @ (posedge clk)
begin
	q <= d;
end
endmodule

10. Two stage D trigger
Two stage D flip-flop, the output data of two stage D flip-flop are different at the same time

module top (d,clk,q,q1);
input d;
input clk;
output reg q;
output q1;
always @(posedge clk)
begin
	q <= d;
end
always @ (posedge clk)
begin
	q1 < q;
end
endmodule

11. D trigger with asynchronous reset
The asynchronous reset is independent of the clock. Once the asynchronous reset signal is valid, the reset operation will be started.

module top(d,rst,clk,q);
input d;
input rst;
input clk;
output reg q;
always @(posedge clk or negedge rst)
begin
if(rst == 1'b0)
q <= 0;
else
q <= d;
end
endmodule
12. D trigger with asynchronous reset and synchronous reset
Asynchronous reset is independent of clock operation, and synchronous reset is synchronized with clock signal.

module top(d,rst,clr,clk,q);
input d;
input rst;
input clr;
input clk;
output reg q;
always @(posedge clk or negedge rst)
begin
	if(rst ==1'b0)
		q <= 0;
	else if(clr ==1'b1)
		q <= 0;
	else
		q<= d;
end
endmodule

13. Shift register
Shift register means that when each clock pulse arrives, it moves one bit to the left or right. Due to the characteristics of D flip-flop, the data output is synchronized with the clock edge, and the output q of each D flip-flop is equal to the output value of the previous D flip-flop, so as to realize the shift operation function.

module top(d,rst,clk,q);
input d;
input rst;
input clk;
output reg[7:0] q;
always @(posedge clk or negedge rst)
begin
	if(rst == 1'b0)
		q <= 0;
	else
		q <= {q[6:0],d};//Shift left
		//q<= {d,q[7:1]};// Shift right
end
endmodule

14. Single port RAM
The write address and read address of single port RAM share the same address. The code is as follows. reg[7:0] ram[63:0] means to define 64 8-bit wide data. Where addr is defined_ Reg can maintain the degree address.

module top
(
	input [7:0] data,
	input [5:0] addr,
	input wr,
	input clk,
	output [7:0] q;
)
	reg [7:0] ram[63:0];//declare ram
	reg [5:0] ADDR_REG;	//addr
	always @(posedge clk)
	begin
		if(wr)
			ram[addr] <= data;
			addr_reg <= addr;
		end
		assign q = ram[addr_reg];//read data
		
endmodule

15. Pseudo dual port RAM
The read-write address of pseudo dual port RAM is independent. You can randomly select the write or read address and perform the read-write operation at the same time.

module top
(
	input [7:0] data,
	input [5:0] write_addr,
	input [5:0] read_addr,
	input [5:0] read+addr,
	input wr,
	input rd,
	input clk,
	output reg[7:0] q
);
reg [7:0] ram[63:0];	//declare ram register
reg [5:0] addr_reg;
always @(posedge clk)
begin
	if(wr)
		ram[write_addr] <= data;
	if(rd)
		q <= ram[read_addr];
end
endmodule

16. True dual port RAM
True dual port RAM has two sets of control lines and data lines, allowing two systems to read and write them

module top
(
	input [7:0] data_a,data_b,
	input [5:0] addr_a,addr_b,
	input wr_a,wr_b,
	input rd_a,rd_b,
	input clk,
	output reg [7:0] q_a,q_b
);
reg [7:0] ram[63:0];
//Port A
always @(posedge clk)
begin
	if(wr_a)		//write
		begin
			ram[addr_a] <= data_a;
			q_a <= data_a;
		end
		if(rd_a)
			q_a <= ram[addr_a];
end
//	Port B
always @(posedge clk)
begin
	if(wr_b)		//write
		begin
			ram[addr_b] <= data_b;
			q_b <=data_b;
		end
		if(rd_b)
		q_b <= ram[addr_b];
end
endmodule

17. Single port ROM
ROM is used to store data. You can initialize ROM according to the following code, but this method is more troublesome to deal with ROMiu with maximum capacity.

module top
(
input [3:0] addr,
input clk,
output reg [7:0] q
);
always @ (posedge clk)
begin
	case(addr)
		4'd0: q<=8'd15;
		4'd1: q<=8'd24;
		4'd2: q<=8'd100;
		4'd3: q<=8'd78;
		4'd4: q<=8'd98;
		4'd5: q<=8'd105;
		4'd6: q<=8'd86;
		4'd7: q<=8'd254;
		4'd8: q<=8'd76;
		4'd9: q<=8'd35;
		4'd10: q<=8'd120;
		4'd11: q<=8'd85;
		4'd12: q<=8'd37;
		4'd13: q<=8'd19;
		4'd14: q<=8'd22;
		4'd15:q<=8'd67;
		default: q<=8'd0;
	endcase
end
endmodule

This section introduces the modules commonly used in combinatorial logic and sequential logic. I hope I can have an in-depth understanding in the future study, use more and think more in the code, which is conducive to rapidly improving the level.

Posted by RiBlanced on Thu, 19 May 2022 15:11:33 +0300