字数 721,阅读大约需 4 分钟
微信号:Jeremy3141592654
公众号:Jeremy27182818
在IC设计的过程中有一些是常见的结构,比如FIFO,仲裁器,排序器,移位器,环形移位器,环形FIFO等,以下就来介绍几种我自己设计过程中才用到的结构。
1 移位器
移位器主要采用的是对数移位器,可以根据所需要移动的位数实现对数据的移位,具体代码如下:
1)右移
// 可以使用generate来参数化这种模块input data;output data_p;wire [02:00] shift_num;wire [31:00] data_s1;wire [31:00] data_s2;wire [31:00] data_s4;assign data_s1 = shift_num[00] ? {1'd0,data[31:01]} : data;assign data_s2 = shift_num[01] ? {2'd0,data_s1[31:02]} : data_s1;assign data_s4 = shift_num[02] ? {4'd0,data_s2[31:04]} : data_s2;assign data_p = data_s4;
2)环形移位器
// 可以使用generate来参数化这种模块input data;output data_p;wire [02:00] shift_num;wire [31:00] data_s1;wire [31:00] data_s2;wire [31:00] data_s4;assign data_s1 = shift_num[00] ? {data[00],data[31:01]} : data;assign data_s2 = shift_num[01] ? {data_s1[01:00],data_s1[31:02]} : data_s1;assign data_s4 = shift_num[02] ? {data_s2[03:00],data_s2[31:04]} : data_s2;assign data_p = data_s4;
2 仲裁器
仲裁器在ic设计的过程中常见的是固定优先级仲裁,以下提供两种常见的写法,其中第二种只需要1条代码就可以实现同样的功能,适合进行参数化,第二种方法主要使用了独热码的特性。
wire [02:00] req;wire [02:00] ack;always @(*) begin if(req[0]) begin ack[0] = 1; end else if(req[1]) begin ack[1] = 1; end else begin ack[2] = 1; endend
wire [02:00] req;wire [02:00] ack;assign ack = (~(req - 1)) & req;
3 环形FIFO
环形FIFO在实现FIR和IIR滤波器中是非常常见的实现方法,环形FIFO主要的核心是通过1个写指针和1个读指针来实现的。
开始写指针和读指针在同一个地址(如图1),为地址1,输入的数据写入地址1,然后将数据读出来运算,先读地址1,然后读地址5,接着是地址4,一直到地址2结束这一次读取的流程,完成一次读取后,指针的相对状态如图2,写指针加1。
图1
图2
当下一个数据进来后,写在地址2,读取过程启动,从2地址开始读取,然后从1地址读取,直到读到3地址结束,最后当写指针前进到5地址,完成整个读的行为后,写指针此时需要回到1地址,再继续重复上述的操作。
我是谁:
我是Jeremy,一个认真工作在芯片行业的数字IC设计工程师,量产了6颗大型芯片,有数十次完整的投片经历,设计过音频,射频基带,校准,存储等模块,正在认真的将自己的所见所闻分享给大家。
我能提供:
1)大型数字设计的设计方法2)快速上手数字设计3)常见的数字设计电路结构