【FPGA学习笔记】VL46 同步FIFO
根据题目提供的双口RAM代码和接口描述,实现同步FIFO,要求FIFO位宽和深度参数化可配置。
电路的接口如下图所示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
`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 ); reg [ 4 : 0 ] wp,rp; //读写指针 //---------------写操作---------------------------------------- always @(posedge clk or negedge rst_n) begin if (!rst_n) wp<= 5 'b0; else if (wenc) wp<=wp+ 1 'b1; end //---------------读操作---------------------------------------- always @(posedge clk or negedge rst_n) begin if (!rst_n) rp<= 5 'b0; else if (renc) rp<=rp+ 1 'b1; end //----------空满信号----------------------------------------- always @(posedge clk or negedge rst_n) begin if (!rst_n) rempty<= 0 ; else if (wp==rp) rempty<= 1 'b1; else rempty<= 1 'b0; end always @(posedge clk or negedge rst_n) begin if (!rst_n) wfull<= 0 ; else if (wp=={!rp[ 4 ],rp[ 3 : 0 ]}) wfull<= 1 'b1; else wfull<= 1 'b0; end //assign rempty=(wp==rp); //这里答案的空满判断是打一拍后再比较的,造成空满判断滞后,应该用组合逻辑 //assign wfull=(wp=={!rp[4],rp[3:0]}); //------------例化------------------------------------- wire wenc,renc; assign wenc=winc&!wfull; assign renc=rinc&!rempty; dual_port_RAM dual_port_RAM( .wclk (clk), .wenc (wenc), .waddr (wp), .wdata (wdata), .rclk (clk), .renc (renc), .raddr (rp), .rdata (rdata) ); endmodule |