典型电路的模板
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