首页 > 其他分享 >牛客进阶题目:同步FIFO

牛客进阶题目:同步FIFO

时间:2023-01-11 22:35:35浏览次数:38  
标签:进阶 WIDTH RAM 端口 FIFO 牛客 DEPTH input

给定一个双端口RAM作为sFIFO的存储空间,所以可以一套端口读,另一套端口写。在sFIFO里维护读写指针各一个,作为DRAM的地址。

判满判空采取扩1bit操作,只有这样才能标识反卷,指示写满。
其余地方根据RAM端口去思考要添加的控制逻辑即可

`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) begin
	if(wenc)
		RAM_MEM[waddr] <= wdata;
end 

always @(posedge rclk) begin
	if(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
);
localparam ADDR_WIDTH = $clog2(DEPTH) ;
reg[ADDR_WIDTH:0]	write_pointer;
reg[ADDR_WIDTH:0]	read_pointer ;
wire		wenc	;
wire		renc 	;

//assign wfull = (raddr == {!waddr[ADDR_WIDTH],waddr[ADDR_WIDTH-1:0]}) ? 1'b1 : 1'b0 ;
//assign rempty= (raddr == waddr) ? 1'b1 : 1'b0 ;

assign	wenc = winc & !wfull	;
assign 	renc = rinc & !rempty	;

always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		wfull <= 1'b0 ;
	else if(read_pointer == {!write_pointer[ADDR_WIDTH],write_pointer[ADDR_WIDTH-1:0]})
		wfull <= 1'b1 ;
	else
		wfull <= 1'b0 ;
end

always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		rempty <= 1'b0 ;
	else if(read_pointer == write_pointer)
		rempty <= 1'b1 ;
	else
		rempty <= 1'b0 ;
end

always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		write_pointer <= 'd0 ;
	else if(winc & !wfull)
		write_pointer <= write_pointer + 1 ;
	else
		write_pointer <= write_pointer ;
end

always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		read_pointer <= 'd0 ;
	else if(rinc & !rempty)
		read_pointer <= read_pointer + 1 ;
	else
		read_pointer <= read_pointer ;
end



dual_port_RAM  
    #(
        .DEPTH(DEPTH),
        .WIDTH(WIDTH)
    )
    dual_port_RAM_U0 
    (
        .wclk(clk),
      .wenc(wenc),
        .waddr(write_pointer[ADDR_WIDTH-1:0]), 
      .wdata(wdata),        
      .rclk(clk),
        .renc(renc),
        .raddr(read_pointer[ADDR_WIDTH-1:0]), 
      .rdata(rdata)     
);       
endmodule

标签:进阶,WIDTH,RAM,端口,FIFO,牛客,DEPTH,input
From: https://www.cnblogs.com/icwangpu/p/17045079.html

相关文章

  • MySql学习笔记-进阶03
          ......
  • #小白进阶之路
    目前的学习状态是算法学完了搜索和图论,目前正在接触动态规划,听了几个背包问题,代码有的地方理解了好久都没有相通,最后还是求助了一下同学。算法学到这感觉上难度了捏,以前以......
  • Nginx 进阶篇
    目录Nginx进阶篇五、服务配置1、配置成系统服务2、配置环境变量六、部署静态资源1、概述2、配置指令2.1listen2.2server_name2.3location2.4root2.5alias2.6i......
  • Java进阶篇——springboot2源码探究
    1.@EnableAutoConfiguration除了元注解之外,EnableAutoConfiguration包含了两大重要部分:1)@AutoConfigurationPackage注解该注解只导入了一个内部类:AutoConfigurationPac......
  • 我的Hexo博客搭建记录,从入门到进阶
    咕,我的个人博客开站啦.目前基于hexo+github配置截止到2023年1月10日,我搭建好这个博客有好几天了,最近也忙着在增改博客的功能.我尽量用简单的语言,记录一下我的工作,如......
  • 进阶阶段——STM32学习笔记(一)
    进阶阶段——STM32学习笔记(1)前言由于套件放在学校,待等假期结束后才能做实验0STM32简介注意:STM32的标准工作电压为3.3V,若用5V供电,需要用(电平转换电路)稳压芯片降压至3.3......
  • webpack进阶
    ##loaderloader用于转换某些类型的模块loader用于对某些导入的资源进行特定处理例如cssimage...###原理loader本质上是一个函数###手写一个babelLoa......
  • C++ 图进阶系列之纵横对比 Bellman-Ford 和 Dijkstra 最短路径求解算法
    1.前言因无向、无加权图的任意顶点之间的最短路径由顶点之间的边数决定,可以直接使用原始定义的广度优先搜索算法查找。但是,无论是有向、还是无向,只要是加权图,最短路径长......
  • 1.9寒假集训-进阶训练赛(五)A-M题解
    前五题网上都有不写了需要注意的是第四题是给定密钥和密文要把它加密算是一个逆过程看了半天都没读懂样例 第六题应该也有但是我写一下因为学校oj这边空间给的是1......
  • 牛客进阶题目20:根据状态转移写状态机-二段式
    把输出段与次态段合并即可`timescale1ns/1nsmodulefsm2( inputwireclk, inputwirerst, inputwiredata, outputregflag);//*************code****......