Gitee仓库:https://gitee.com/Shaoyang1202/FPGA_Verilog
组合逻辑
组合逻辑电路的输出信号只与当前时刻输入信号有关,无储存电路。
多路选择器
也称多路开关,可以将多路信号中任意一路选择出来作为输出
- 实例:二输入选择器
RTL文件:
module Data_selector
(
input wire [0:0] in_1,//[0:0]表示1位宽,1位宽也可以不写
input wire in_2,//input+wire/reg(类型)+位宽+信号名
input wire sel ,
output reg out //最后一条信号后面不用加逗号
);
//使用always进行赋值
always@(*) //()内是敏感条件,*表示任何信号有电平变化就执行,等于always@(sel,in_1,in_2)
if(sel == 1'b1) //当sel为高电平时
begin //如果只有一行赋值,begin、end可省略
out = in_1; //组合逻辑要用阻塞赋值
end
else
out = in_2;
endmodule
tb文件:
`timescale 1ns/1ns //时间单位/时间精度
module tb_Data_selector();
reg in_1;
reg in_2;
reg sel ;
wire out ;
initial //上电只执行一次,给输入信号赋初值
begin
in_1 <= 1'b0; //非阻塞赋值
in_2 <= 1'b0;
sel <= 1'b0;
end
always #10 in_1 <= {$random} % 2; //十个时间单位的延时,随机数对2取余非零即1,每隔10个时间单位对in_1赋值
always #10 in_2 <= {$random} % 2;
always #10 sel <= {$random} % 2;
initial
begin
$timeformat(-9,0,"ns",6); //设置时间格式的系统函数,-9表示10的-9次方->纳秒,0表示保留到小数点后0位
$monitor("@time %t:in_1=%b in_2=%b sel=%b out=%b",$time,in_1,in_2,sel,out);//对电平变化实时打印
end
Data_selector Data_selector_inst1 //对模块实例化
(
.in_1(in_1), //alt+左键可以列选择
.in_2(in_2), //将仿真模块中生成的模块中的信号与被仿真模块连接
.sel (sel),
.out (out)
);
endmodule
添加tb文件
选择tb文件位置:
ModelSim仿真
仿真结果
译码器
理论
译码是编码的逆过程,可分为变量译码、显示译码,
实战-三八译码器
- always实现:
/*
always语句实现2022/4/27
*/
module Decoder
(
input wire in_1,
input wire in_2,
input wire in_3,
output reg [7:0] out
);
always@(*)
if({in_1,in_2,in_3} == 3'b000) //输入信号拼接
out = 8'b0000_0001; //_增加可读性,无实际意义
else if({in_1,in_2,in_3} == 3'b001)
out = 8'b0000_0010 ;
else if({in_1,in_2,in_3} == 3'b010)
out = 8'b0000_0100 ;
else if({in_1,in_2,in_3} == 3'b011)
out = 8'b0000_1000 ;
else if({in_1,in_2,in_3} == 3'b100)
out = 8'b0001_0000 ;
else if({in_1,in_2,in_3} == 3'b101)
out = 8'b0010_0000 ;
else if({in_1,in_2,in_3} == 3'b110)
out = 8'b0100_0000 ;
else if({in_1,in_2,in_3} == 3'b111)
out = 8'b1000_0000 ;
else
out = 8'b0000_0001;
endmodule
综合电路图:
2. case实现
module Decoder
(
input wire in_1,
input wire in_2,
input wire in_3,
output reg [7:0] out
);
always@(*)
case({in_1,in_2,in_3})
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;
default:out = 8'b0000_0001; //避免launch
endcase
endmodule
综合电路图:
always语句实现有优先级区别,case没有优先级,所以case实现综合后为数据选择器
- 仿真:
tb文件
`timescale 1ns/1ns
module Decoder_tb();
reg in_1;
reg in_2;
reg in_3;
wire [7:0] out;
initial
begin
in_1 <= 1'b0;
in_2 <= 1'b0;
in_3 <= 1'b0;
end
always #10 in_1 <= {$random} % 2;
always #10 in_2 <= {$random} % 2;
always #10 in_2 <= {$random} % 2;
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("@time %t:in_1=%b in_2=%b in_3=%b out=%b",$time,in_1,in_2,in_3,out);
end
Decoder Decoder_inst //模块实例化
(
.in_1(in_1), //(in_1)是仿真模块中生成的,与仿真模块中一致
.in_2(in_2),
.in_3(in_3),
.out(out)
);
endmodule
在ModelSim仿真界面ctrl+a
可以选中所有波形,选中波形后ctrl+g
可以对波形进行分组,图示位置可以显示/隐藏变量的路径
如图、可以设置变量显示的进制
仿真结果: