电子设备知识网-中国电子设备,国内最专业电子设备平台
电子设备知识网-中国电子设备,国内最专业电子设备平台

如何设计参数化数据选择器

需求:

FPGA设计中,大部分情况下我们都得使用到数据选择器。并且为了设计参数化,可调,通常情况下我们需要一个参数可调的数据选择器,比如M选1,M是可调的参数。

如果,数据选择器是不带优先级的,我们可以使用 verilog VHDL中的二维数组进行设计 例如,这样综合编译器也是可以正确生成对应的电路

 reg[7:0]din[1:0];assign dout = din[sel];

当我们,需要设计一个参数化的数据选择器时呢?我们该如何设计呢?以下罗列三种实现方式

方式一:嵌套if来实现:

假设我们的多路选择器,在某些情况下最多位M路,那么我们可以嵌套M个if,这样,我们就设计出了参数可调 2~M的多路选择器。

 always@(*)begin    if(sel[0])//1        dout = din[0*DATA_SIZE+:DATA_SIZE];    else if(sel[1])//2        dout = din[1*DATA_SIZE+:DATA_SIZE];    else if(sel[2])//3        dout = din[2*DATA_SIZE+:DATA_SIZE];    else if(sel[3])//4        dout = din[3*DATA_SIZE+:DATA_SIZE];    else if(sel[4])//5        dout = din[4*DATA_SIZE+:DATA_SIZE];    else if(sel[5])//6        dout = din[5*DATA_SIZE+:DATA_SIZE];    else if(sel[6])//7        dout = din[6*DATA_SIZE+:DATA_SIZE];    else if(sel[7])//8        dout = din[7*DATA_SIZE+:DATA_SIZE];    else//0        dout = 0;en

方式二:casez实现:

 always @(*)begincasez(sel)8'b0000_0001:dout=din[0*DATA_SIZE+:DATA_SIZE];8'b0000_001?:dout=din[1*DATA_SIZE+:DATA_SIZE];8'b0000_01??:dout=din[2*DATA_SIZE+:DATA_SIZE];8'b0000_1???:dout=din[3*DATA_SIZE+:DATA_SIZE];8'b0001_????:dout=din[4*DATA_SIZE+:DATA_SIZE];8'b001?_????:dout=din[5*DATA_SIZE+:DATA_SIZE];8'b01??_????:dout=din[6*DATA_SIZE+:DATA_SIZE];8'b1???_????:dout=din[7*DATA_SIZE+:DATA_SIZE];default:dout=0;     endcaseend

方式三:采用与门或门搭建。

比如一个二选一的数据选择器应该,这样一个结构:

如何设计参数化数据选择器

一个三选一,带优先级的电路结构

如何设计参数化数据选择器

也就是说,我们可以通过代码,描述出这样一个电路结构,通过逻辑复制的语句完成参数化的设计。

具体思路是这样的,先把地址信号sel 变成只是优先级高的那位为1,其他信号为0。例如,低位高优先级,sel=1100,变换后sel_prio=0100。然后,将sel_prio与上对应的数据,可以看出来只有1的那个数据才会被选通,其他为0

 module mux#(    parameter DATA_SIZE = 8,    parameter NUM  = 8)(    input  [NUM*DATA_SIZE-1:0]  din,input[NUM-1:0]sel,output[DATA_SIZE-1:0]dout); assigndout=mux_prio(din,sel);function[DATA_SIZE-1:0]mux_prio;    input  [NUM*DATA_SIZE-1:0]  din;    input  [NUM-1:0]        sel;        reg [NUM-1:0] dat;    integer i,j;    begin        for(i=0;i            for(j=0;j                dat[j] = din[j*DATA_SIZE+i];            end            mux_prio[i] = mux_prio_bit(dat,sel_prio(sel));        end    endendfunctionfunction [NUM-1:0] sel_prio ;    input [NUM-1:0] sel;    reg temp;    integer i,j;    begin        sel_prio[0] = sel[0];        for(i=1;i            begin                temp = 0;                for(j=0;j                    begin                        temp = temp | sel[j];                    end                sel_prio[i] = sel[i] && !temp;            end        endendfunctionfunctionmux_prio_bit;    input  [NUM-1:0]  din;    input  [NUM-1:0]  sel;    integer i;    begin        mux_prio_bit = din[0]&&sel[0];        for(i=1;i            mux_prio_bit = mux_prio_bit | (din[i]&sel[i]);        endendfunctionendmodule

方式四:基于行为级描述。

在前面的设计中我们是根据数据选择器的电路结构,用硬件语言描述出了这样的电路,那么我们能不能只描述其功能,然后让编译器帮我们理解呢?

 module mux#(    parameter DATA_SIZE = 8,    parameter NUM  = 8)(    input  [NUM*DATA_SIZE-1:0]  din,    input  [NUM-1:0]            sel,        output  [DATA_SIZE-1:0]      dout    );assign dout = mux_prio_a(din,sel);//基于功能,行为级的描述function  [DATA_SIZE-1:0]      mux_prio_a ;    input  [NUM*DATA_SIZE-1:0]  din;    input  [NUM-1:0]        sel;    reg temp;    integer i;    begin        temp = 1;        mux_prio_a = 0;        for(i=0;i            if(temp && sel[i])begin                temp = 0;                mux_prio_a = din[i*DATA_SIZE+:DATA_SIZE];            end        end    endendfunctionendmodule

总结:

1、首先,这里提供了了四种描述参数可配的带优先级的多路选择器的描述方法。第一种和第二种是常规的描述方法推荐if-else结构,第三种是根据电路结构使用HDL描述,第四种是使用代码描述了其功能。

2、第三种方法从功能描述,看起来描述简单,好理解,不过这样的描述方式是看综合软件的“智能化程度”的,因为FPGA是基于查找表LUT结构的,这样的描述方式在描述比较简单的电路功能,综合器是可以正确理解的。如果比较复杂的电路,不推荐用这样的描述方式。

3、值得注意的是,FPGA设计最重要的是理解低层的电路结构,实现过程最好是 功能–》电路–》HDL描述该电路,这才是最好的设计。使用类似第三种描述方式最好还是掌握理解底层电路结构,然后看综合出来的是不是你需要的电路


原文标题:Verilog实现可参数化的带优先级的数据选择器

文章出处:【微信公众号:FPGA自习室】欢迎添加关注!文章转载请注明出处。

审核编辑:彭菁

未经允许不得转载:电子设备知识网 » 如何设计参数化数据选择器

分享到: 生成海报