基礎から始める Verilog (見ながら練習・テストシミュレーション) - メモ

講義1

1. インバータ
ここに画像の説明を挿入します
コード

//反相器设计;
`timescale 1ns/10ps
module inv(
								A,
								Y
								);
input						A;
output					Y;

assign 					Y=~A;

endmodule

//----testbench of inv-------
module inv_tb;
reg         aa;
wire 				yy;
inv         inv(
								.A(aa),
								.Y(yy)
								);

initial begin
				     aa<=0;
				#10  aa<=1;
				#10  aa<=0;
				#10  aa<=1;
				#10  $stop;
				
end

endmodule		

2. 8 ビット インバータ
ここに画像の説明を挿入します
3. NAND ゲート
ここに画像の説明を挿入します
コード:

//与非门;
`timescale 1ns/10ps
module nand_gate(
							A,
							B,
							Y
							);
input					A;
input					B;
output				Y;

assign				Y = ~(A & B);
endmodule

//-------testbench of nand_gate-----
module nand_gate_tb;
reg						aa,bb;
wire					yy;
nand_gate nand_gate(
							.A(aa),
							.B(bb),
							.Y(yy)
							);
							
initial begin
						  	  aa<=0; bb<=0;
						#10 	aa<=0; bb<=1;
						#10 	aa<=1; bb<=0;
						#10 	aa<=1; bb<=1;
						#10 	$stop;
			
end

endmodule

4. 4 ビット NAND ゲート
ここに画像の説明を挿入します
コード:

//与非门;
`timescale 1ns/10ps
module nand_gate_4bits(
										A,
										B,
										Y
										);
input[3:0]					A;
input[3:0]					B;
output[3:0]				  Y;

assign							Y = ~(A & B);
endmodule

//-------testbench of nand_gate-----
module nand_gate_4bits_tb;
reg[3:0]										aa,bb;
wire[3:0]										yy;
nand_gate nand_4bits_gate(
														.A(aa),
														.B(bb),
														.Y(yy)
														);
							
initial begin
						  	  aa<=4'b0000; bb<=4'b1111;
						#10 	aa<=4'b0010; bb<=4'b0110;
						#10 	aa<=4'b0111; bb<=4'b0100;
						#10 	aa<=4'b0000; bb<=4'b1110;
						#10 	$stop;
			
end

endmodule

1. テストベンチにはポートがないため、括弧はありません
2. テストベンチの入力は後で変更されるため、レジスタ 3 として定義されます
#10: 10 時間単位後; 'タイムスケール 1ns/10ps、これは時間単位です1ns の時間精度と 10ps の時間精度
4. reg タイプ 変数に値を代入する場合は、等号「<=」と矢印を使用します。

講義2

1. ロジックを 1 つ選択します
ここに画像の説明を挿入します

ここに画像の説明を挿入します

//二选一逻辑设计
`timescale 1ns/10ps
module fn_sw(
									a,
									b,
									sel,
									y
									);
input							a;
input					   	b;
input							sel;
output						y;

//assign 						y = sel?(a^b):(a&b);

//用always 语句块实现组合逻辑
reg 							y;
always@(a or b or sel) begin
	if(sel==1)begin
		y = a^b;
	end
	else begin
		y = a&b;
  end
end
endmodule

//---------testbench of fn_sw------------
module fn_sw_tb;

reg               a, b, sel;
wire							y; 

fn_sw fn_sw(
									.a(a),
									.b(b),
									.sel(sel),
									.y(y)
									);
									
initial begin
									a<=0;b<=0;sel<=0;
						#10   a<=0;b<=0;sel<=1;
						#10   a<=0;b<=1;sel<=0;
						#10   a<=0;b<=1;sel<=1;
						#10   a<=1;b<=0;sel<=0;
						#10   a<=1;b<=0;sel<=1;
						#10   a<=1;b<=1;sel<=0;
						#10   a<=1;b<=1;sel<=1;
						#10   $stop;
end

endmodule

3. case ステートメントを使用して複数選択ロジックを実装します
ここに画像の説明を挿入します
。コード:

//四选一逻辑
`timescale 1ns/1ps
module fn_sw_4(
										a,
										b,
										sel,
										y
										);
input 							a;
input 							b;
input[1:0]					sel;
output 							y;
	
reg 								y;
always@(a or b or sel)begin
	case(sel)
		2'b00:begin y <= a&b;end
		2'b01:begin y <= a|b;end
		2'b10:begin y <= a^b;end
		2'b11:begin y <= ~(a^b);end
	endcase
end
		
endmodule

//-------testbench of fn_sw_4----------
module fn_sw_4_tb;
reg[3:0]						absel;
fn_sw_4 fn_sw_4(
										.a(absel[0]),
										.b(absel[1]),
										.sel(absel[3:2]),
										.y(y)
										);
										
initial begin
							  absel<=0;   //先赋初始值
					#200  $stop;
end

always #10 absel<=absel+1;   //每过10ns,absel加一,这样经过16次加一,可以取完四位寄存器所有可能,并观察y的取值
endmodule

シミュレーション結果:
ここに画像の説明を挿入します
概要:
ここに画像の説明を挿入します
1. always@(a または b または sel) の a、b、c は敏感な変数、入力です。入力が複数ある場合は複数の入力を記述します
2. に代入される変数は常に reg 型である必要があります。
3. $stop システムタスク
4. マルチプレクサ

講義3

1. 補数コード変換
ここに画像の説明を挿入します
コード:

//补码转换逻辑
`timescale 1ns/10ps
module comp_conv(
											 a,
											 a_comp
											 );
											 
input[7:0]             a;
output[7:0]            a_comp;

wire[6:0]              b;//按位取反的幅度位
wire[7:0]              y;//负数的补码

assign                 b=~a[6:0];
assign                 y[6:0]=b+1;//按位取反+1
assign                 y[7]=a[7];//符号位不变

assign                 a_comp=a[7]==1?y:a;//二选一
//assign               a_comp=a[7]?{
    
    a[7],~a[6:0]+1}:a;//可替换上面的wire和assign语句
endmodule 

//----------testbench of comp_conv--------
module comp_conv_tb;
reg[7:0]               a_in;
wire[7:0]              y_out;
comp_conv comp_conv(
											 .a(a_in),
											 .a_comp(y_out)
											 );
initial begin 
												a_in<=0;
							#3000     $stop;
end
	
always#10 a_in=a_in+1;
endmodule

ここに画像の説明を挿入します
2. 7セグメントデジタルチューブデコーダ
ここに画像の説明を挿入します
コード:

//七段码译码器
`timescale 1ns/10ps
module seg_dec(
														num,
														a_g
														);
input[3:0]                 num;
output[6:0]                a_g;//a_g-->{
    
    a,b,c,d,e,f,g}

reg[6:0]                   a_g;
always@(num)begin
	case(num)
		4'd0: a_g<=7'b111_1110; 
		4'd1: a_g<=7'b011_0000;  
		4'd2: a_g<=7'b110_1101;  
		4'd3: a_g<=7'b111_1100;  
		4'd4: a_g<=7'b011_0011;  
		4'd5: a_g<=7'b101_1011;  
		4'd6: a_g<=7'b101_1111;  
		4'd7: a_g<=7'b111_0000;  
		4'd8: a_g<=7'b111_1111;  
		4'd9: a_g<=7'b111_1011;  
		default: a_g<=7'b000_0001;  //中杠
	endcase
	
end

endmodule

//--------test bench of seg_dec---------
module seg_dec_tb;
reg[3:0]                    num_in;
wire[6:0]                   a_g_out;
seg_dec seg_dec(
														.num(num_in),
														.a_g(a_g_out)
														);
initial begin 
														num_in<=0;
								#100        $stop;
end														
														
always #10 num_in<=num_in+1;															
endmodule

図に示すように、入力 3 は 111_1110 であるはずで、波形図によればこれは正しいです。
ここに画像の説明を挿入します

まとめ:
ここに画像の説明を挿入します

講義4

1. カウンター
ここに画像の説明を挿入します
コード:

//计数器
`timescale 1ns/10ps
module counter(
								clk,
								res,
								y
								);
input           clk;
input           res;
output[7:0]     y;

reg[7:0]        y;
wire[7:0]        sum;//+1运算的结果(1)
assign           sum=y+1;//组合逻辑部分(2)

always@(posedge clk or negedge res)
if(~res) begin
	y<=0;
end
else begin
	y<=sum;             //可省略上面(1)(2)语句,y<=y+1;
end
endmodule


//--------testbench of counter------
module counter_tb;
reg             clk,res;
wire[7:0]       y;

counter counter(
								.clk(clk),
								.res(res),
								.y(y)
								);
								
initial begin
								clk<=0;res<=0;
				#17     res<=1;
			  #6000   $stop;
end

always #5 clk<=~clk;

endmodule

シミュレーション結果:
ここに画像の説明を挿入します
レベル 2 および 4 の擬似ランダム コード ジェネレーター
ここに画像の説明を挿入します
ここに画像の説明を挿入します

コード:

//四级伪随机码发生器
`timescale 1ns/10ps
module m_gen(
											clk,
											res,
											y
											);
input                 clk;
input                 res;
output                y;

reg[3:0]              d;
assign                y=d[0];

always@(posedge clk or negedge res)
if(~res)begin
	d<=4'b1111;
end
else begin
	d[2:0]<=d[3:1];      //右移一位
	d[3]<=d[3]+d[0];     //模二加
end

endmodule

//-------testbench of m_gen-------
module m_gen_tb;
reg                    clk,res;
wire                   y;
m_gen m_gen(
											.clk(clk),
											.res(res),
											.y(y)
											);
											
initial begin
						clk=0;res=0;
		#17     res=1;
		#600   $stop;
end
always #5 clk=~clk;

endmodule

シミュレーション波形図:
ここに画像の説明を挿入します
ここに画像の説明を挿入します
概要:
ここに画像の説明を挿入します

講義5

講義6

講義 7

講義8

講義9

講義10

おすすめ

転載: blog.csdn.net/qq_43374681/article/details/132621306