实验1、组合逻辑
教程
Verilog HDL拥有非常自由的语法,条条大路通罗马。
1、2-4译码器的三种写法
module decoder2_4 (
decode_in,
decode_out
);
input [1:0] decode_in;
output [3:0] decode_out;
//写出逻辑表达式,然后像卡诺图一样写出来
assign decode_out[0] = ~decode_in[1] & ~decode_in[0];
assign decode_out[1] = ~decode_in[1] & decode_in[0];
assign decode_out[2] = decode_in[1] & ~decode_in[0];
assign decode_out[3] = decode_in[1] & decode_in[0];
endmodule
module decoder2_4 (
decode_in,
decode_out
);
input [1:0] decode_in;
output [3:0] decode_out;
//用?:语句写
assign decode_out = decode_in[0] ?
(decode_in[1]? 4'b1000: 4'b0010):
(decode_in[1]? 4'b0100: 4'b0001);
endmodule
module decoder2_4 (
decode_in,
decode_out
);
input [1:0] decode_in;
output reg [3:0] decode_out;
always @(*) begin //组合逻辑的always块写法,这样就可以用if-else或者case语句啦
if (decode_in == 2'b00)
decode_out = 4'b0001;
else if (decode_in == 2'b01)
decode_out = 4'b0010;
else if (decode_in == 2'b10)
decode_out = 4'b0100;
else if (decode_in == 2'b11)
decode_out = 4'b1000;
end
endmodule
2、Testbench验证
第一步:先写一下testbench decoder_testbench.v
:
`timescale 1ns/1ns
`include "decoder2_4.v"
module decoder_testbench;
reg [1:0] in;
wire [3:0] out1,out2,out3;
decoder2_4_1 dut0(
.decode_in (in)
, .decode_out (out1)
);
decoder2_4_2 dut1(
.decode_in (in)
, .decode_out (out2)
);
decoder2_4_3 dut2(
.decode_in (in)
, .decode_out (out3)
);
integer i; //integer is a 32b unsigned integer
initial begin
$dumpfile("wave.vcd");
$dumpvars(0);
end
initial begin
$monitor("time=%4d, in=%4b, out0=%04b, out1=%04b, out2=%04b", $time, in, out1, out2, out3);
// $monitor为Verilog系统自带函数, 格式像c++的printf一样,意为“每当要print的变量发生变化即打印”,同理还有$display(仅在当前仿真运行时间打印一样结果)
for(i=0; i<8; i=i+1) begin
#10 in = i;
end
end
endmodule
用iverilog快速验证一下:
cd [到当前存放dff.v和dff_tb.v的文件夹] # 进入工作目录
iverilog -o wave decoder_testbench.v # 将dff_tb.v编译为wave可执行文件
vvp -n wave #运行该可执行文件进行仿真(simulation)
如果到此运行顺利的话,当前文件夹会生成一个新的wave.vcd(正如dff_tb.v里面写的$dumpfile(“wave.vcd”)所写)。然后用gtkwave打开这个波形:
gtkwave wave.vcd
就可以得到。你之前预测的结果是正确的么?
由于我们的testbench.v里写了$monitor(每当里面涉及的variable)
3、2-4译码器的FPGA实现验证
请根据以下教程,将上述testbench和三种decoder的设计置于FPGA上实验,输入用按键。
参考:
练习
1、奇偶校验码 (parity check code)设计
奇偶校验码是最简单的查错编码 (error detection code),其行为是输入m位码字,如果有奇数个1则编码器输出1;如果有偶数个1则编码输出为0。
Note
[问题1] 用Verilog HDL设计一个输入有16位的奇偶校验码,并写testbench验证。
提示:这是对于输入位的什么按位逻辑操作?一种逻辑操作即可搞定。
2、温度计码 (thermometer code)设计
温度计码是模数转换器ADC中常用的编码,一个温度计码解码器的例子为:
输入 |
输出 |
---|---|
0000000 |
000 |
0000001 |
001 |
0000011 |
010 |
0000111 |
011 |
0001111 |
100 |
0011111 |
101 |
0111111 |
110 |
1111111 |
111 |
它就是长得像温度计。
Note
[问题2]
2.1 用Verilog HDL设计一个输入是1023位的温度计解码器,用组合逻辑实现上述功能,并写testbench验证。
2.2 温度计码很容易出错哦,比如出现1000011码字,在问题2.1的基础上改进加入报错端口,一旦有错码字,报错端口error=1,否则保持为0。请完成一个全新的设计:带校验功能的温度计解码!
提示:Verilog HDL支持for loop, Verilog-2005 standard manual。