Verilog基础练习
- [1 累加累乘器](#1 累加累乘器)
- [2 异或、与运算求解](#2 异或、与运算求解)
-
- [2.1 匹配4种case下的求解](#2.1 匹配4种case下的求解)
- [3 补码计算器](#3 补码计算器)
- [4 计数器](#4 计数器)
1 累加累乘器
c
`timescale 1ns/10ps
module inout_test();
parameter ratio = 2;
reg [15:0]num ;
reg [31:0]save_add_v;
reg [31:0]save_multi_v;
initial
begin
save_add_v = 100;
save_multi_v = 100;
forever begin
save_add_v = save_add_v + ratio;
save_multi_v = save_multi_v * ratio;
#1;
$display("This is a test program");
$display("save_add_v:%d,save_multi_v:%d" , save_add_v , save_multi_v);
if($time >4)
$finish;
end
end
endmodule;
输出:
2 异或、与运算求解
c
`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);
reg y;
always@(a ,b , sel)
begin
if(sel == 1)
y = a^b;
else
y = a & b;
end
endmodule;
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<=1;b<=0;sel<=0;
#10 a<=0;b<=1;sel<=0;
#10 a<=0;b<=1;sel<=1;
#10 a<=1;b<=0;sel<=0;
#10 $stop;
end;
endmodule;
2.1 匹配4种case下的求解
c
`timescale 1ns/10ps
module fn_sw( a , b , sel , y );
input a;
input b;
input [1:0]sel;
output y;
//assign y = sel? (a^b):(a&b);
reg y;
always@(a ,b , sel)
begin
case(sel)
2'b00:
y<= a&b;
2'b01:
y<= a|b;
2'b10:
y<= a^b;
2'b11:
y<=~(a^b);
endcase
end
endmodule;
module fn_sw_tb;
reg a,b;
reg [1:0]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<=2;
#10 a<=1;b<=0;sel<=3;
#10 a<=0;b<=1;sel<=0;
#10 a<=0;b<=1;sel<=1;
#10 a<=1;b<=0;sel<=2;
#10 a<=1;b<=0;sel<=3;
#10 $stop;
end;
endmodule;
3 补码计算器
正数的补码是本身;
负数的补码是符号位不变,其他位,安位取反后加1;
以8 bit数为例,可操作的位数是[6:0]
bash
`timescale 1ns/1ns
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]?y:a; //2选1
endmodule;
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
负数的补码:
正数的不变:
其中计算补码的部分,也可用一句assign 实现:
c
assign a_comp = a[7] ? {a[7], ~a[6:0]+1}:a;
![](https://i-blog.csdnimg.cn/direct/26b16df9097f449a9de8491a0a5dd46a.png)
4 计数器
每产生一个上升沿,计数值加1
c
`timescale 1ns/10ps
module counter(
clk,
reset,
y,
sum
);
input clk , reset;
output [15:0]y;
reg [15:0] y;
output wire [15:0] sum;// +1 运算结果
reg [15:0]p_sum;
assign sum = y + 1;
always @(posedge clk or negedge reset )
begin
if (~reset)
y <= 0;
else
y <= sum;
end
endmodule
module counter_tb;
reg clk,reset;
wire [15:0] y;
wire [15:0] sum;
counter counter(
.clk(clk),
.reset(reset),
.y(y),
.sum(sum)
);
initial
begin
clk <= 0; reset <= 0;
#17 reset <= 1;
#2880;
$display("counter num is:%d", sum);
$stop;
end
always #5 clk <= ~clk;
endmodule
结果:
设定simulation run time 的地方: