写在前面的话
数据选择器在数字电路设计中的应用尤为广泛。同时,作为基础的电路功能单元,也比较适合作为初学者的入门实验。现在梦翼师兄陪大家一起来设计一个最基础的数据选择器。
项目需求
设计一个二选一数据选择器,然后用一路控制信号选择输出数据选通哪一路输入的数据信号。
系统架构
模块功能介绍
模块名 |
功能描述 |
mux2 |
通过Data_sel 选择输出结果的值 |
顶层模块端口描述
端口名 |
端口说明 |
Data_a |
A通道数据输入 |
Data_b |
B通道数据输入 |
Data_out |
数据输出端 |
Data_sel |
数据选通控制 |
代码解释
mux2代码解释
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function:二选一多路器 *****************************************************/ 00 module mux2( 01 data_a, //A通道数据输入 02 data_b, //B通道数据输入 03 data_sel, //输出数据选通信号 04 data_out //数据输出 05 ); 06 //系统输入 07 input data_a; //A通道数据输入 08 input data_b; //B通道数据输入 09 input data_sel; //输出数据选通信号 10 //系统输出 11 output reg data_out;//数据输出 12 //二选一多路器控制逻辑 13 always@(*) 14 begin 15 if(data_sel)//选通信号为高电平 16 data_out=data_a;//输出结果为A通道数据 17 else //选通信号为低电平 18 data_out=data_b;//输出结果为B通道数据 19 end 20 endmodule |
01~05行列出了多路器所有输入/输出接口,07~11行定义了端口属性,13~19行描述了二选一多路器的逻辑功能。
仿真代码
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function:多路器测试代码 *****************************************************/ 00 `timescale 1ns/1ps //仿真时间单位是ns,仿真时间精度是ps 01 module mux2_tb; 02 03 reg data_a, data_b; //仿真激励数据a,b信号端口 04 reg data_sel; //仿真激励数据选择信号端口 05 06 wire data_out; //仿真结果输出信号 07 08 initial begin 09 data_a = 0; //data_a复初始值等于0 10 data_b = 0; //data_b复初始值等于0 11 data_sel = 0; //data_sel复初始值等于0 12 #200 data_a = 0; data_b = 1; //200ns之后,data_a=0;data_b=1; 13 #200 data_a = 1; data_b = 0; //200ns之后,data_a=1;data_b=0; 14 #200 data_a = 1; data_b = 1; //200ns之后,data_a=1;data_b=1; 15 #200 data_a = 0; data_b = 0; data_sel = 1; //200ns之后,data_a=0;data_b=0;data_sel=1; 16 #200 data_a = 0; data_b = 1; //200ns之后,data_a=0;data_b=1; 17 #200 data_a = 1; data_b = 0; //200ns之后,data_a=1;data_b=0; 18 #200 data_a = 1; data_b = 1; //200ns之后,data_a=1;data_b=1; 19 #400 $stop; //400ns之后,仿真结束 20 end 21 22 mux2 mux2( //把激励信号送进mux2模块 23 .data_a(data_a), 24 .data_b(data_b), 25 .data_sel(data_sel), 26 .data_out(data_out) 27 ); 28 29 endmodule |
仿真分析
仿真图可知,当Data_sel为低电平的时候,Data_out=Data_b,当Data_sel为高电平的时候,Data_out=Data_a,Data_out的输出由Data_sel的电平来决定,满足了二选一数据选择器的要求。
6.1.8 二选一数据寄存
下面我们将二选一数据选择器的结构改造一下,使二选一数据选择器的输出端连接有寄存器
编写代码如下
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function:二选一多路器(带寄存器输出) *****************************************************/ 00 module mux2_clk( 01 clk, //时钟信号输入 02 rst_n, //复位信号输入 03 data_a, //数据a输入 04 data_b, //数据b输入 05 data_sel, //数据选择信号 06 data_out //数据输出 07 ); 08 09 input clk, rst_n; //时钟信号,复位信号输入端口 10 input data_a, data_b; //数据a,b端口输入 11 input data_sel; //数据选择信号端口 12 13 output data_out; //数据输出端口 14 15 reg data_out; 16 17 always@(posedge clk or negedge rst_n) //沿触发检测 18 begin 19 if(!rst_n) 20 data_out <= 1'd0; //复位初始化 21 else if(data_sel) 22 data_out <= data_a; //当data_sel为高电平,输出data_a 23 else 24 data_out <= data_b; //当data_sel为低电平,输出data_b 25 end 26 27 endmodule |
仿真代码
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function:二选一多路器测试代码(带寄存器输出) *****************************************************/ 00 `timescale 1ns/1ps //仿真时间单位是ns,仿真时间精度是ps 01 module mux2_clk_tb; 02 03 reg clk, rst_n; //仿真激励时钟,复位信号端口 04 reg data_a, data_b; //仿真激励数据a,b信号端口 05 reg data_sel; //仿真激励数据选择信号端口 06 07 wire data_out; //仿真结果输出信号 08 09 initial begin 10 clk = 0; //时钟信号初始化 11 rst_n = 0; //复位信号有效 12 data_a = 0; //data_a复初始值等于0 13 data_b = 0; //data_b复初始值等于0 14 data_sel = 0; //data_sel复初始值等于0 15 #200.1 rst_n = 1; //复位结束 16 #200 data_a = 0; data_b = 1; //200ns之后,data_a=0;data_b=1; 17 #200 data_a = 1; data_b = 0; //200ns之后,data_a=1;data_b=0; 18 #200 data_a = 1; data_b = 1; //200ns之后,data_a=1;data_b=1; //200ns之后,data_a=0;data_b=0;data_sel=1; 19 #200 data_a = 0; data_b = 0; data_sel = 1; 20 #200 data_a = 0; data_b = 1; //200ns之后,data_a=0;data_b=1; 21 #200 data_a = 1; data_b = 0; //200ns之后,data_a=1;data_b=0; 22 #200 data_a = 1; data_b = 1; //200ns之后,data_a=1;data_b=1; 23 #400 $stop; //400ns之后,仿真结束 24 end 25 26 always#50 clk = ~clk; //产生1Mhz时钟信号 27 28 mux2_clk mux2_clk( //把激励信号送进mux2_clk模块 29 .clk(clk), 30 .rst_n(rst_n), 31 .data_a(data_a), 32 .data_b(data_b), 33 .data_sel(data_sel), 34 .data_out(data_out) 35 ); 36 37 endmodule |
查看仿真波形如下
由仿真图可知,当Data_sel的电平发生变化时,Data_out的输出结果在时钟上升沿到来的时候才会变化,输出的结果被时钟同步化了。