建设产品网站课程,html网页制作菜鸟教程,鄞州区卖场设计网站建设,免费律师咨询平台牛客网Verilog刷题——VL46 题目解析答案 题目 根据题目提供的双口RAM代码和接口描述#xff0c;实现同步FIFO#xff0c;要求FIFO位宽和深度参数化可配置。电路的接口如下图所示。 双口RAM端口说明#xff1a; 同步FIFO端口说明#xff1a; 双口RAM代码如下#xff… 牛客网Verilog刷题——VL46 题目解析答案 题目 根据题目提供的双口RAM代码和接口描述实现同步FIFO要求FIFO位宽和深度参数化可配置。电路的接口如下图所示。 双口RAM端口说明 同步FIFO端口说明 双口RAM代码如下可在本题答案中添加并例化此代码。
module dual_port_RAM #(parameter DEPTH 16,parameter WIDTH 8)(input wclk
,input wenc
,input [$clog2(DEPTH)-1:0] waddr //深度对2取对数得到地址的位宽。
,input [WIDTH-1:0] wdata //数据写入
,input rclk
,input renc
,input [$clog2(DEPTH)-1:0] raddr //深度对2取对数得到地址的位宽。
,output reg [WIDTH-1:0] rdata //数据输出
);reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];always (posedge wclk) begin
if(wenc)
RAM_MEM[waddr] wdata;
end always (posedge rclk) begin
if(renc)
rdata RAM_MEM[raddr];
end endmodule 输入输出描述
信号类型输入/输出位宽描述clkwireIntput1读写时钟信号rstnwireIntput1读写异步复位信号低电平有效wincwireIntput1写使能信号rincwireIntput1读使能信号wdatawireIntputWIDTH写数据wfullwireOutput1写满信号remptywireOutput1读空信号rdatawireOutputWIDTH读数据
解析 同步FIFO中读操作与写操作均在同一时钟域下进行不涉及跨时钟域操作所以只需要用一个计数器来计数当前FIFO中存储的实际数据个数写入数据个数减去读出数据个数再用于判断产生空满信号即可。所以同步FIFO设计的要点就在于以下几点
空满信号判断
答案
timescale 1ns/1ns
/**********************************RAM************************************/
module dual_port_RAM #(parameter DEPTH 16,parameter WIDTH 8)(input wclk,input wenc,input [$clog2(DEPTH)-1:0] waddr //深度对2取对数得到地址的位宽。,input [WIDTH-1:0] wdata //数据写入,input rclk,input renc,input [$clog2(DEPTH)-1:0] raddr //深度对2取对数得到地址的位宽。,output reg [WIDTH-1:0] rdata //数据输出
);reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];always (posedge wclk) beginif(wenc)RAM_MEM[waddr] wdata;
end always (posedge rclk) beginif(renc)rdata RAM_MEM[raddr];
end endmodule /**********************************SFIFO************************************/
module sfifo#(parameter WIDTH 8,parameter DEPTH 16
)(input clk , input rst_n ,input winc ,input rinc ,input [WIDTH-1:0] wdata ,output reg wfull ,output reg rempty ,output wire [WIDTH-1:0] rdata
);//---------------------------------
// 使用内部计数器设计同步FIFO
//---------------------------------
reg [$clog2(DEPTH)-1:0] waddr;
reg [$clog2(DEPTH)-1:0] raddr;
reg [$clog2(DEPTH):0] cnt;//内部计数器
always (posedge clk or negedge rst_n)if(!rst_n)cnt d0;else if(!wfull !rempty winc rinc)cnt cnt;else if(!wfull winc)cnt cnt 1;else if(!rempty rinc)cnt cnt - 1;elsecnt cnt;//空满判断
always (posedge clk or negedge rst_n)if(!rst_n) beginwfull 1b0;rempty 1b0;endelse if(cnt DEPTH) beginwfull 1b1;rempty 1b0;endelse if(cnt 0) beginwfull 1b0;rempty 1b1;endelse beginwfull 1b0;rempty 1b0;end//写地址
always (posedge clk or negedge rst_n)if(!rst_n)waddr d0;else if(!wfull winc)waddr waddr 1d1;elsewaddr waddr;//读地址
always (posedge clk or negedge rst_n)if(!rst_n)raddr d0;else if(!rempty rinc)raddr raddr 1d1;elseraddr raddr;//双端口RAM例化
dual_port_RAM
#( .DEPTH(DEPTH),.WIDTH(WIDTH)
)
dual_port_RAM_inst
(.wclk(clk),.wenc(winc !wfull),.waddr(waddr), //深度对2取对数得到地址的位宽。.wdata(wdata), //数据写入.rclk(clk),.renc(rinc !rempty),.raddr(raddr), //深度对2取对数得到地址的位宽。.rdata(rdata) //数据输出
);endmodule