Menu Close

数据分配器及Verilog实现

  1. 数据分配器工作原理
    数据分配器与数据选择器正好为功能互反的结构,数据选择器时间多路数据选择到一路输出,是多选一的开关。而数据分配器是将一路信号分配到多路上,是一到多的开关,有时也称为多路分 配器、多路调节器, 简称DEMUX,其电路 为单输入、多输出形 式。4路分配器原理框图如图 1所示。

 

%title插图%num

图1

例1:用Verilog描述4位数据分配器,用与或非的方式实现

module distribute4
(
    input  [1:0] sel,
    input        D,
    output [3:0] Y
);
 
assign Y[0] = ~sel[1] & ~sel[0] & D;
assign Y[1] = ~sel[1] &  sel[0] & D;
assign Y[2] =  sel[1] & ~sel[0] & D;
assign Y[3] =  sel[1] &  sel[0] & D;
 
endmodule

 

例2:

module distribute8
(
    input [2:0] sel,
    input        D,
    output [7:0] Y
);
 
assign Y[0] = ~sel[2] & ~sel[1] & ~sel[0] & D;
assign Y[1] = ~sel[2] & ~sel[1] &  sel[0] & D;
assign Y[2] = ~sel[2] &  sel[1] & ~sel[0] & D;
assign Y[3] = ~sel[2] &  sel[1] &  sel[0] & D;
assign Y[4] =  sel[2] & ~sel[1] & ~sel[0] & D;
assign Y[5] =  sel[2] & ~sel[1] &  sel[0] & D;
assign Y[6] =  sel[2] &  sel[1] & ~sel[0] & D;
assign Y[7] =  sel[2] &  sel[1] &  sel[0] & D;
 
endmodule

 

例3:利用问号在Verilog描述中实现4路数据分配器

module distribute4
(
    input  [1:0] sel,
    input        D,
    output [3:0] Y
);
 
assign Y[0] = (sel==2'b00) ? D : 0;
assign Y[1] = (sel==2'b01) ? D : 0;
assign Y[2] = (sel==2'b10) ? D : 0;
assign Y[3] = (sel==2'b11) ? D : 0;
 
endmodule

其他方法1:

module distribute4
(
    input  [1:0] sel,
    input        D,
    output [3:0] Y
);


always @ (*)
begin 
    Y = 0;
    Y[sel] = D;
end
 
endmodule

其他方法2:

module distribute4
(
    input  [1:0] sel,
    input        D,
    output [3:0] Y
);
 
assign Y = D << sel;

endmodule

 

例4:利用if语句实现8路数据分配器

module distribute8if
(
    input      [2:0] a,
    input            D,
    output reg [7:0] y
);
 
 
always@(*)  
begin
    y                  = 8'b0;
    if(a==0)      y[0] = D;
    else if(a==1) y[1] = D;
    else if(a==2) y[2] = D;
    else if(a==3) y[3] = D;
    else if(a==4) y[4] = D;
    else if(a==5) y[5] = D;
    else if(a==6) y[6] = D;
    else if(a==7) y[7] = D;
end
 
endmodule

 

例5:利用case语句实现8路数据分配器

module distribute8case
(
    input      [2:0] a,
    input            D,
    output reg [7:0] y
);
 
always@(*)  
begin
    y = 8'b0;
 
    case(a)
    0: y[0] = D;
    1: y[1] = D;
    2: y[2] = D;
    3: y[3] = D;
    4: y[4] = D;
    5: y[5] = D;
    6: y[6] = D;
    7: y[7] = D;
    default: y = 8'b0;
    endcase
end
 
 
endmodule

 

仿真程序如下:

`timescale 1 ns / 1 ps
 
module tb_dis ();
 
reg [2:0] a;
reg D;
wire [7:0] y;
 
initial begin
a = 3'b000;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b000;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b001;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b001;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b010;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
a = 3'b010;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b011;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b011;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b100;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
a = 3'b100;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b101;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
a = 3'b101;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b101;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
a = 3'b101;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b110;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
a = 3'b110;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b111;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
a = 3'b111;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b1xx;
D = 1'b0;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b1xx;
D = 1'b1;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
 
a = 3'b1xx;
D = 1'bX;
#10
$display("time =%t, a= %b, D= %b, y= %b ",$time ,a,D,y);
end
 
distribute8case distribute8case_inst
(
.a (a),
.D (D),
.y (y)
 
);
 
 
endmodule

 

$display 函数打出来的信息如下:

%title插图%num

图2

Vivado的仿真波形如图3

%title插图%num

 

图3

从$display 函数打印结果及图3的仿真波形可以看出,无论使用组合逻辑电路的与或非方程,Verilog的“?”选择语句,还是Always过程中的case或if选择语句,在不考虑”X“值作为输入的情况下,得到的结果都相同。

2. 数据分配器的扩展

上面的例子演示了一位数据分配到不同输出端口的简单的数据分配器,真正更有使用价值的数据分配器是数据分配器的扩展使用,下面列出几种经常用于扩展的情况,具体细节在相关课程中会讲解。

(1) 由一位位宽的数据扩展为多位输入数据,因此由2进制的一位扩展到数据分配与共享。

(2)由独占模式(可以分时复用)扩展到多用户共享模式,

(3)有数据扩展到数据包的模式,形成数据交换,如总线系统

(4)配合数据选择器,由一对多扩展到多对多的模式,实现数据交换,如网络交换机的实现。

 

Posted in FPGA, FPGA, Quartus II, Verilog, Verilog

发表评论

相关链接