FIFO 的概念
1、FIFO(Frist Input Frist Output),即先入先出,也是一种存储器,一般做数据缓冲。
2、FIFO 和 RAM 的共同点在于都能存储数据、都有控制写和读的信号;不同点在于FIFO没有地址,所以不能任意指定读取某一个数据,数据只能按照数据输入 的顺序输出,即先入先出,并且读写可以同时进行。
3、如果数据把 FIFO 的深度写满了,数据将不能再进去,也不会覆盖原有的数据; 读 FIFO 的数据也只能读一遍,读完一遍FIFO就空了,需要再往 FIFO 写数据才能读出新数据,否则读出的数据一直是最后一次读 FIFO 时的数据。
First-Word Fall-Through 模式广泛用于数据缓冲应用,特点相对读使能 0 延时输出读出数据,其原理是第一个数据永远不需要读使能就自动呈现在读端口上。 Standard 模式用于输出端时序特性要求比较高的场合,特点相对读使能输出1拍延迟,也可以设置多拍延迟这样经过寄存器大拍提高输出寄存器间的时序特性。
设计任务:
写一个 fifo 控制器,输入的数据是 86 行 86 列的矩阵,数据由串口传输过来,传 过来的数据先一行一行用 fifo 缓存,然后每三行的同一列进行一次加,即第 0,1,2 行,第 1,2,3 行……第 84,85,86 行,每三行作为一组,每一组的每一列的三个数 据进行一次加运算。
实现思路:
a、串口传输过来的 86x86 个数据是每十个波特时间才传输一次,所以需要控制 fifo 的写使能每十个波特才能拉高一次。
b、因为是三行数据相加,所以可以把前面两行的数据先存到 fifo 里面(第 0 行存 fifo1,第 1 行存 fifo2),当第三行数据传输过来的时候,再把三个数据(两个 fifo 输 出端和 rx 输出)相加。
c、第 0,1,2 行加完后,需要把第 1,2,3 行数据相加,这时第 0,1,2 行的数据已经不 在了,所以需要在相加的时候把后面两行(第 1,2 行)数据存到 fifo 里面,即相加的同时需要将 fifo2 的数据存入 fifo1,pi_data 的数据存入 fifo1。
d、最后三行相加的时候,最后一行不需要存到 fifo2 里面,最后两行不需要存到 fifo1 里面。因此要往 fifo1存入的数据为第 0,1,2…83 行;要往 fifo2 存入的数据为第 1,2,3…84 行;需要进行加运算的次数为84x86 次。
e、数据相加时需要控制每 10 个波特时间,fifo 读出一个数据。
顶层模块设计
顶层模块示意图:
顶层模块代码实现:
module uart_top(
input wire clk,
input wire rst_n,
input wire rx,
input wire tx
);
wire [7:0] pi_data;
wire pi_flag;
wire [7:0] po_sum;
wire po_flag;
fifo_ctrl fifo_ctrl_inst(
.clk(clk),
.rst_n(rst_n),
.rx_data(pi_data),
.pi_flag(pi_flag),
.po_sum(po_sum),
.po_flag(po_flag)
);
uart_rx uart_rx_inst(
.clk(clk),
.rst_n(rst_n),
.rx(rx),
.po_data(pi_data),
.po_flag(pi_flag)
);
uart_tx uart_tx_inst(
.clk(clk),
.rst_n(rst_n),
.pi_flag(po_flag),
.pi_data(po_sum),
.tx(tx)
);
endmodule
接收模块设计
接收模块示意图: