一、前言
本文旨在记录FPGA开发的学习内容,主要包括38译码器的代码实现,和相关的Verilog语法知识,方便本人后续的回顾与复习同时,也希望与读者进行相关交流。文章内容可能存在错误,还望指正。
二、原理讲解
38译码器的工作原理及电路层结构略,详见数字电路讲解。
1、真值表:
a | b | c | Out[7:0] |
0 | 0 | 0 | 0000_0001 |
0 | 0 | 1 | 0000_0010 |
0 | 1 | 0 | 0000_0100 |
0 | 1 | 1 | 0000_1000 |
1 | 0 | 0 | 0001_0000 |
1 | 0 | 1 | 0010_0000 |
1 | 1 | 0 | 0100_0000 |
1 | 1 | 1 | 1000_0000 |
2、代码
module decoder_3_8(
a,
b,
c,
out
);
input a;
input b;
input c;
output reg [7:0] out;
always@(*)begin
case({a,b,c})
3'b000:out=8'b0000_0001;
3'b001:out=8'b0000_0010;
3'b010:out=8'b0000_0100;
3'b011:out=8'b0000_1000;
3'b100:out=8'b0001_0000;
3'b101:out=8'b0010_0000;
3'b110:out=8'b0100_0000;
3'b111:out=8'b1000_0000;
endcase
end
endmodule
3、代码解析
模块decoder_3_8()中有3个输入接口,1个输出接口,因此在括号中必须定义。并且要定义输入接口、输出接口或者输入输出双向接口。
以always块描述的信号赋值,被赋值对象(等号左侧)必须定义为reg类型。
对于一个位宽为n的变量temp,其定义方式为 [n-1:0] temp。位宽从0~n-1,总计为n。
在对输出out进行定义时,可以有两种等价的方式:
1: output reg [7:0] out;
2: output [7:0] out;
reg [7:0] out;
在always(*)中,其表示着监测所有变量的变化,*通常表示通配符,代指所有的变量。
{a,b,c}意味着对于变量a,b,c进行位拼接
在位拼接中,还有一种表示
wire [3:0] d;
assign d = {a,1’b0,b,c}
其中,可以拼接常量0在第二位,也就是{a0bc}。
对于进制数的表示:
b 二进制 3’b101 8’b0000_1010
o 八进制 3'o5 8'o12(需要区分0和o)
d 十进制 3’d5 8’d10
h 十六进制 3’h5 8’ha
4、测试平台代码
`timescale 1ns/1ps
module decoder_3_8_tb();
reg s_a;
reg s_b;
reg s_c;
wire [7:0] out;
decoder_3_8 inst(
.a(s_a),
.b(s_b),
.c(s_c),
.out(out)
);
initial begin
s_a=0;s_b=0;s_c=0;#200
s_a=0;s_b=0;s_c=1;#200
s_a=0;s_b=1;s_c=0;#200
s_a=0;s_b=1;s_c=1;#200
s_a=1;s_b=0;s_c=0;#200
s_a=1;s_b=0;s_c=1;#200
s_a=1;s_b=1;s_c=0;#200
s_a=1;s_b=1;s_c=1;#200
$stop;
end
endmodule
5、代码解析
在测试平台xxx_tb中测试模块decoder_3_8_tb中不存在任何实际的接口,因此也不做定义。
其中`timescale 1ns/1ps描述了测试平台的时间步长和时间精度,前者为步长,后者为精度,在该测试平台中,时间可以描述为,1ns、1.001ns,也就是可以达到ps级别,但是在实际调试和板级测试中,精度达到1ns级别足矣,即`timescale 1ns/1ns。
#200,代表着延时200个时间单位,在该测试平台中,表示延时200ns。
这种延时语法只能够在测试平台中使用,放在正常的设计代码中无法使用,因为fpga中没有能够实现延时的硬件部分。
在vivado自带的仿真中,可以不用加$stop语句,会自动停止仿真
但是如果采用modelsim仿真,则必须加上,modelsim只有识别到$stop才会停止仿真。
initial语句表示了测试平台的激励部分,同always相似,既可以将所有的激励都写在一个initial语句块中,也可以分散在多个不同的initial语句块中。
由于fpga的作用机制,很多语句块都是并行发生的,也就是说很多语句块中描述的语法都是同时进行的。类比于C语言的串行发生机制,C语言中,必须按照编码的上下顺序执行程序,只有在上一个语句执行完成后,才能执行下一个语句。而在Verilog中,在完成对于变量的定义后,所有的always语句块和assign语句块都是同时执行的。
总结
以上就是本人对于38译码器的fpga实现的学习,初次接触相关内容可能理解不足,后续将进一步补充内容。