SOC课程——③——Verilog程序(典型电路的模板)

13 篇文章 2 订阅

1 模板代码

1.1 输出时序逻辑的模板代码

1.1.1 异步复位的时序电路(用的最多)

	always@(posedge clk or negedge rst_n)begin
		if(rst_n == 1'b0)begin
		    (这里写代码,如 "out <= 0;" )
		end
		else begin
			(这里写代码,如"out <= out_temp;")	
		end
	end

1.1.2 同步复位的时序电路

	always@(posedge clk)begin
		if(rst_n == 1'b0)begin
		    (这里写代码,如 "out <= 0;" )
		end
		else begin
			(这里写代码,如"out <= out_temp;")	
		end
	end

1.2 输出组合逻辑的模板代码

	always@(*)begin
		(这里写代码,如 "out_temp = out + 1'b1;" )
	end

1.3 输出整个模块部分代码

module module_name(
		clk,
		rst_n,
		// 其他信号,如dout
		dout
	);

	//参数定义
	parameter DATA_W = 

	//输入信号定义
	input	clk	;
	input	rst_n;

	// 输出信号定义
	output[DATA_W-1:0]	dout;
	
	//输出信号reg定义
	reg	[DATA_W-1:0]	dout;
		
	//中间信号定义
	reg				signal1;
	
	//组合逻辑写法
	always@(*)begin
		(这里写代码,如 "out_temp = out + 1'b1;" )
	end

	//时序逻辑写法
	always@(posedge clk or negedge rst_n)begin
		if(rst_n == 1'b0)begin
		    (这里写代码,如 "out <= 0;" )
		end
		else begin
			(这里写代码,如"out <= out_temp;")	
		end
	end
endmodule

1.4 输出测试文件(testbench)的模板代码

'timescale 1ns/1ns
module testbench_name();

	//时钟和复位
	reg clk;
	reg rst_n;

	//uut的输入信号
	reg[3:0]	din0;
	reg			din1;
	......(等信号)
	
	//uut的输出信号
	wire		dout0;
	wire[4:0]	dout1;
	......(等信号)
	
	// 时钟周期,单位是ns,可在此修改时钟周期
	parameter CYCLE	= 20;
	
	//复位时间,此时表示复位3个时钟周期的时间
	parameter	RST_TIME = 3;
	
	//待测试的模块例化
	module_name uut(
		.clk	(clk	),
		.rst_n	(rst_n	),
		.din0	(din0	),
		.din1	(din1	),
		.dout0	(dout0	),
		.dout1	(dout1	)
		......(等信号)
	);

	//生成本地时钟50M
	initial begin
		clk	=	0;
		forever
		#(CYCLE/2)
		clk=~clk;
	end

	//产生复位信号
	initial begin
		rst_n = 1;
		#2
		rst_n = 0;
		#(CYCLE*RST_TIME);
		rst_n = 1;
	end
	
	//输入信号din0赋值方式
	initial begin
		#1;
		//赋初值
		din0 = 0;
		#(10*CYCLE)
		//开始赋值
		(开始赋值的语句)
	end

	//输入信号din1赋值方式
	initial begin
		#1;
		//赋初值
		din0 = 0;
		#(10*CYCLE)
		//开始赋值
		(开始赋值的语句)
	end

endmodule

2 典型电路的Verilog代码

2.1 自加一电路add_1(如:n++)

在这里插入图片描述
代码

module add_1(
	clk,
	rst_n,
	out
);

	parameter DATA_W = 4;

	input clk;
	input rst_n;
	output[DATA_W-1:0] out;  
	
	reg [DATA_W-1:0] out;
	
	reg [DATA_W-1:0] out_temp;

	always@(*)begin
		out_temp = out + 1'b1;
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(rst_n == 1'b0)begin
			out <= 0;
		end
		else begin
			out <= out_temp;	
		end
	end
endmodule

2.2 半加器

在这里插入图片描述

module h_adder(A,B,SO,CO);
	
	input	A	;
	input	B	;
	output	SO	;
	output	CO	;

	assign	SO = A ^ B;
	assign	CO = A & B;
	
endmodule

2.3 多路选择器

在这里插入图片描述

  • 包含四个输入端,两个控制端,一个输出端

2.3.1 4选1多路选择器及其case语句表述

  • 知识点:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 代码

module MUX41a(a,b,c,d,s1,s0,y);

	input	a,b,c,d;
	input	s0,s1;
	output	y;

	reg	y;
	
	always@(*)begin 
		case({s1,s0})
			2'b00:	y=a;
			2'b01:	y=b;
			2'b10:	y=c;
			2'b11:	y=d;
		endcase
	end

endmodule

2.3.2 4选1多路选择器及assign语句表述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

module MUX41_2(a,b,c,d,s1,s2,y);
	input	a,b,c,d,s1,s2;
	output	y;
	
	//定义中间变量
	wire	[1:0]	sel;
	wire		at,bt,ct,dt;
	
	assign	sel = {s1,s2}; //并位运算
	assign	at = (sel == 2'd0);
	assign	bt = (sel == 2'd1);
	assign	ct = (sel == 2'd2);
	assign	dt = (sel == 2'd3);

	assign	y = (a&at)|(b&bt)|(c&ct)|(d&dt);
endmodule

2.3.3 4选1多路选择器及条件赋值语句表述

在这里插入图片描述

2.3.4 4选1多路选择器及条件语句表述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4 16选1选择器

module  mux16_1(
	input	[3:0]	sel,
	input	[15:0]	D,
	output			Y
	);
	assign	Y = D[sel];
endmodule

在这里插入图片描述

2.5 8位全加器

在这里插入图片描述

在这里插入图片描述

2.6 BCD码加法器

在这里插入图片描述

(整理和更新中…)

3 典型例题与答案

3.1 例题1

在这里插入图片描述
代码

module mul_module(
	mul_a,
	mul_b,
	clk,
	rst_n,
	mul_result
	);

	parameter	A_W = 4;
	parameter	B_W = 3;
	parameter	C_W = A_W + B_W;

	input[A_W-1:0]	mul_a;
	input[B_W-1:0] 	mul_b;
	input		clk;
	input		rst_n;

	output[C_W-1:0]	mul_result;

	reg[C_W-1:0]	mul_result;
	reg[C_W-1:0]	mul_result_tmp;
	
	always@(*)begin
		mul_result_tmp = mul_a*mul_b;
	end

	always@(posedge clk or negedge rst_n)begin
		if(rst_n == 1'b0)begin
			mul_result <= 0;
		end
		else begin
			mul_result <= mul_result_tmp;
		end
	end

endmodule

3.2 例题2

在这里插入图片描述
分析过程和中间变量
在这里插入图片描述

代码

module mul2port(
	din_a,
	din_b,
	din_c,
	din_d,
	sel_a,
	sel_b,
	clk,
	rst_n,
	result_a,
	result_b
);

	input[2:0] din_a;
	input[1:0] din_b;
	input[3:0] din_c;
	input[3:0] din_d;
	input 	   sel_a;
	input      sel_b;
	input 	   clk;
	input      rst_n;
	output[6:0] result_a;
	output[5:0] result_b;

	reg  [6:0] result_a;
	reg  [5:0] result_b;
	reg  [3:0] sel_dout;

	wire [6:0] result_a_tmp;
	wire [5:0] result_b_tmp;

	reg 	   sel;
	

	always@(posedge clk or negedge rst_n) begin
		if(rst_n == 1'b0)begin
			result_b <= 0;
		end
		else begin
			result_b <= result_b_tmp;
		end
	end

	always@(posedge clk or negedge rst_n) begin
		if(rst_n == 1'b0)begin
			result_a <= 0;
		end
		else begin
			result_a <= result_a_tmp;
		end
	end

	mul_module#(.A_W(3),.B_W(4)) mul_4_3(
		.mul_a	(din_a),
		.mul_b	(sel_dout),
		.clk	(clk),
		.rst_n	(rst_n),
		.mul_result (result_a_tmp)
	);

	mul_module#(.A_W(2),.B_W(4)) mul_4_2(
		.mul_a	(din_b),
		.mul_b	(sel_dout),
		.clk	(clk),
		.rst_n	(rst_n),
		.mul_result (result_b_tmp)
	);
	
	always@(*)begin
		if(sel == 0)
			sel_dout = din_a;
		else 
			sel_dout = din_b;
	end

	always@(posedge clk or negedge rst_n)begin
		if(rst_n == 1'b0)begin
			sel <= 0;
		end
		else begin
			sel = sel_a & sel_b;
		end
	end
	
endmodule
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值