根据输入编码进行解码,解码输出的bit位中只有一个与其余位不一样。这里默认为2-4解码器。
| 输入select | 输出z |
|---|---|
| 00 | 1110 |
| 01 | 1101 |
| 10 | 1011 |
| 11 | 0111 |
//文件路径:a.11/src/decoder.v
module decoder(enable,select,z); //声明模块名以及端口列表
parameter SELECT_WIDTH = 2; //指定输入端select的位宽参数,该参数可以通过例化进行传递
localparam Z_WIDTH = (1 << SELECT_WIDTH);//根据SELECT_WIDTH参数来计算出本地参数
//即输出端位宽
input enable; //解码的使能端口,只有为1的时候才开始解码
input[SELECT_WIDTH-1:0] select; //输入的待解码的选择端口
output reg [Z_WIDTH-1:0] z; //输出结果的端口
always@(enable or select or z)begin //用于解码的组合逻辑,只要敏感列表中的信号变化就重新计算输出结果
if(enable)
z = ({Z_WIDTH{1'b1}} ^ (1 << select));
else
z = {Z_WIDTH{1'b1}};
end
endmodule
测试模块
//文件路径:a.11/sim/testbench/demo_tb.sv
module top;
localparam SELECT_WIDTH = 2;
localparam Z_WIDTH = (1 << SELECT_WIDTH);
logic enable;
logic[SELECT_WIDTH-1:0] select;
logic[Z_WIDTH-1:0] z;
decoder #(.SELECT_WIDTH(SELECT_WIDTH)) DUT(.enable(enable),.select(select),.z(z));
initial begin
$display("%t -> Start!!!",$time);
enable = 0;
select = 0;
#10ns;
enable = 1;
#10ns;
$display("%t -> select: %h z: %b",$time,select,z);
repeat(10)begin
select++;
#10ns;
$display("%t -> select: %h z: %b",$time,select,z);
end
$display("%t -> Finish!!!",$time);
$finish;
end
endmodule
注意这里连接到DUT的观测信号必须是logic类型,这是一种在SystemVerilog中的常见数据类型,而我们这里的测试模块是用SysteVerilog写的,并且仿真时加入仿真选项使得VCS支持SystemVerilog的语法。
因为logic类型支持四态值的类型,从而能够监测到DUT输入输出端口上的不定态x或高阻态z,以在测试验证DUT的过程中,排除出现x或z的特殊值是由功能错误所导致的问题。
通常我们都会在接口interface上使用该类型来将DUT连接到测试平台,具体我们后面课程会讲。
仿真结果运行./run.do脚本后,查看仿真日志sim.log,然后打开dve查看波形。
修改例化模块时传递的参数,并再次验证。
本章实例的配套代码下载附上本章的代码供参考,下载下来导入到虚拟机中,动手跑跑仿真,看看波形,从而加深理解。
链接:https://pan.baidu.com/s/1PGCE8-v3e4IK9HNW21vTZg
提取码:i4hl
公众号:程序员Marshall



