Verilog数据选择器参数化设计

        摘要:Verilog 数据选择器 参数化

1、使用场景

        在有些场景下,需要用到可参数化的数据选择器。比如,将DDR设计成多通道时,地址的选通和数据的选通,需要实现多选一。实际工程当中需要把DDR划分成几个通道是不确定的,所以数据选择器是从几路里面选择一路是不确定的。常规做法是用case语句实现数据选择器,然而,Verilog的case语句不够灵活,无法做到参数化,就无法做到通用性。这个时候就引出了数据选择器的参数化设计。

2、工程实现

        数据选择器的参数化设计,其核心就是二维数组,通过二维数组索引的方式实现可以做到参数化。下面是具体代码实现,仅供参考。

        模块代码:

module binary_mux #(
    parameter dataNum   = 5,
    parameter dataWidth = 8,
    parameter log2N     = (dataNum == 1) ? 1 : $clog2(dataNum)
) (
    input  wire  [log2N-1:0]                    sel,
    input  wire  [dataNum*dataWidth-1:0]        din,
    output reg   [dataWidth-1:0]                dout
);

    wire  [dataWidth-1:0]                       din_array [2**log2N-1:0];

    generate
        begin
            genvar i;
            for (i = 0; i < 2**log2N; i = i + 1) begin
                if (i < dataNum) begin
                    assign din_array[i] = din[dataWidth*i +: dataWidth];
                end else begin
                    assign din_array[i] = din[dataWidth*0 +: dataWidth];
                end
            end
        end
    endgenerate

    always@(*)begin
        dout = din_array[sel];
    end

    //
    /*
    binary_mux #(.dataNum (dataNum ), .dataWidth (dataWidth )) u_binary_mux(.sel (sel ), .din (din ), .dout (dout ));
    */

endmodule

        RTL原理图:

7228d61ba96c41e1a7eb410dd2c9d322.png

        仿真模块:

//~ `New testbench
`timescale  1ns / 1ps

module tb_binary_mux;

// unit_data_mux Parameters
parameter PERIOD     = 10;
parameter dataNum    = 5;
parameter dataWidth  = 8;
parameter log2N      = (dataNum == 1) ? 1 : $clog2(dataNum);

// unit_data_mux Inputs
reg   clk                                  = 1 ;
reg   reset                                = 1 ;
reg   [log2N-1:0]  sel                     = 0 ;
reg   [dataNum*dataWidth-1:0]  din       = 0 ;

// unit_data_mux Outputs
wire  [dataWidth-1:0]  dout                ;


initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

initial
begin
    #(PERIOD*2) reset  =  0;
end

always @(posedge clk ) begin
    if (reset) begin
        din[dataWidth*0 +: dataWidth] <= 'd1;
        din[dataWidth*1 +: dataWidth] <= 'd2;
        din[dataWidth*2 +: dataWidth] <= 'd3;
        din[dataWidth*3 +: dataWidth] <= 'd4;
        din[dataWidth*4 +: dataWidth] <= 'd5;
        sel                           <= 'd0;
    end else begin
        din <= din;
        sel <= sel + 'd1;
    end
end

binary_mux #(
    .dataNum   ( dataNum   ),
    .dataWidth ( dataWidth ))
 u_binary_mux (
    .sel                     ( sel   [log2N-1:0]               ),
    .din                     ( din   [dataNum*dataWidth-1:0]   ),

    .dout                    ( dout  [dataWidth-1:0]           )
);

endmodule

        仿真波形:

1dfe053a5c6641419abfc3f14918795a.png

        说明:这里的数据个数不一定需要是2^N,没有这个限制,可自行设置非2^N的整数倍时的默认输出值,这里设计的是默认输出是0路。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值