介绍:此为设计AVS帧内预测与MD之间的接口FIFO,在已有的FIFO基础上设计得来:(1)其在满状态下若在输入数据,会冲掉前面第一个数据;(2)根据输入模式的不同,会选择从第几个数据开始为有效数据(即前面的为无效数据)。
内容:指标(1)由读写指针的移位来实现
指标(2)由复位信号的初始值来实现
FIFO module
Code
1 //-----------------------------------------------------
2 // Design Name : syn_fifo
3 // File Name : syn_fifo.v
4 // Function : Synchronous (single clock) FIFO
5 // Coder :
6 //-----------------------------------------------------
7 module syn_fifo (
8 clk , // Clock input
9 rst , // Active high reset
10 wr_cs , // Write chip select
11 rd_cs , // Read chipe select
12 data_in , // Data input
13 rd_en , // Read enable
14 wr_en , // Write Enable
15 data_out , // Data Output
16 empty , // FIFO empty
17 full , // FIFO full
18 mode // Mode
19 );
20
21 // FIFO constants
22 parameter DATA_WIDTH = 8;
23 parameter ADDR_WIDTH = 8;
24 parameter RAM_DEPTH = (1 << ADDR_WIDTH);
25 // Port Declarations
26 input clk ;
27 input rst ;
28 input mode;
29 input wr_cs ;
30 input rd_cs ;
31 input rd_en ;
32 input wr_en ;
33 input [DATA_WIDTH-1:0] data_in ;
34 output full ;
35 output empty ;
36 output [DATA_WIDTH-1:0] data_out ;
37
38 //-----------Internal variables-------------------
39 reg [ADDR_WIDTH-1:0] wr_pointer;
40 reg [ADDR_WIDTH-1:0] rd_pointer;
41 reg [ADDR_WIDTH :0] status_cnt;
42 reg [DATA_WIDTH-1:0] data_out ;
43 wire [DATA_WIDTH-1:0] data_ram ;
44 reg c;
45
46 //-----------Variable assignments---------------
47 assign full = (status_cnt == (RAM_DEPTH));
48 assign empty = (status_cnt == 0);
49
50 //-----------Code Start---------------------------
51 always @ (posedge clk or posedge rst)
52 begin : WRITE_POINTER
53 if (rst) begin
54 wr_pointer <= 0;
55 c <= 0;
56 end else if (wr_cs && wr_en )
57 begin
58 if(wr_pointer ==7)begin
59 c <= 1;
60 wr_pointer <=wr_pointer +1;
61 end
62 else begin
63 wr_pointer <= wr_pointer + 1;
64 end
65 end
66 end
67
68 always @ (posedge clk or posedge rst)
69 begin : READ_POINTER
70 if (rst) begin
71 if(mode == 2)begin
72 rd_pointer <= 2;
73 end
74 else if(mode == 1)begin
75 rd_pointer <= 1;
76 end
77 else if(mode == 0)begin
78 rd_pointer <= 0;
79 end
80 end else begin
81 if (rd_cs && rd_en ) begin
82 rd_pointer <= rd_pointer + 1;
83 end
84 if(c==1 && wr_pointer ==rd_pointer + 1 )begin
85 rd_pointer <= rd_pointer + 1;
86 end
87 end
88 end
89
90 always @ (posedge clk or posedge rst)
91 begin : READ_DATA
92 if (rst) begin
93 data_out <= 0;
94 end else if (rd_cs && rd_en ) begin
95 data_out <= data_ram;
96 end
97 end
98
99 always @ (posedge clk or posedge rst)
100 begin : STATUS_COUNTER
101 if (rst) begin
102 status_cnt <= 0;
103 // Read but no write.
104 end else if ((rd_cs && rd_en) && !(wr_cs && wr_en)
105 && (status_cnt != 0)) begin
106 status_cnt <= status_cnt - 1;
107 // Write but no read.
108 end else if ((wr_cs && wr_en) && !(rd_cs && rd_en)
109 && (status_cnt != RAM_DEPTH)) begin
110 status_cnt <= status_cnt + 1;
111 end
112 end
113
114 ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM (
115 .address_0 (wr_pointer) , // address_0 input
116 .data_0 (data_in) , // data_0 bi-directional
117 .cs_0 (wr_cs) , // chip select
118 .we_0 (wr_en) , // write enable
119 .oe_0 (1'b0) , // output enable
120 .address_1 (rd_pointer) , // address_q input
121 .data_1 (data_ram) , // data_1 bi-directional
122 .cs_1 (rd_cs) , // chip select
123 .we_1 (1'b0) , // Read enable
124 .oe_1 (rd_en) // output enable
125 );
126
127 endmodule
128
1 //-----------------------------------------------------
2 // Design Name : syn_fifo
3 // File Name : syn_fifo.v
4 // Function : Synchronous (single clock) FIFO
5 // Coder :
6 //-----------------------------------------------------
7 module syn_fifo (
8 clk , // Clock input
9 rst , // Active high reset
10 wr_cs , // Write chip select
11 rd_cs , // Read chipe select
12 data_in , // Data input
13 rd_en , // Read enable
14 wr_en , // Write Enable
15 data_out , // Data Output
16 empty , // FIFO empty
17 full , // FIFO full
18 mode // Mode
19 );
20
21 // FIFO constants
22 parameter DATA_WIDTH = 8;
23 parameter ADDR_WIDTH = 8;
24 parameter RAM_DEPTH = (1 << ADDR_WIDTH);
25 // Port Declarations
26 input clk ;
27 input rst ;
28 input mode;
29 input wr_cs ;
30 input rd_cs ;
31 input rd_en ;
32 input wr_en ;
33 input [DATA_WIDTH-1:0] data_in ;
34 output full ;
35 output empty ;
36 output [DATA_WIDTH-1:0] data_out ;
37
38 //-----------Internal variables-------------------
39 reg [ADDR_WIDTH-1:0] wr_pointer;
40 reg [ADDR_WIDTH-1:0] rd_pointer;
41 reg [ADDR_WIDTH :0] status_cnt;
42 reg [DATA_WIDTH-1:0] data_out ;
43 wire [DATA_WIDTH-1:0] data_ram ;
44 reg c;
45
46 //-----------Variable assignments---------------
47 assign full = (status_cnt == (RAM_DEPTH));
48 assign empty = (status_cnt == 0);
49
50 //-----------Code Start---------------------------
51 always @ (posedge clk or posedge rst)
52 begin : WRITE_POINTER
53 if (rst) begin
54 wr_pointer <= 0;
55 c <= 0;
56 end else if (wr_cs && wr_en )
57 begin
58 if(wr_pointer ==7)begin
59 c <= 1;
60 wr_pointer <=wr_pointer +1;
61 end
62 else begin
63 wr_pointer <= wr_pointer + 1;
64 end
65 end
66 end
67
68 always @ (posedge clk or posedge rst)
69 begin : READ_POINTER
70 if (rst) begin
71 if(mode == 2)begin
72 rd_pointer <= 2;
73 end
74 else if(mode == 1)begin
75 rd_pointer <= 1;
76 end
77 else if(mode == 0)begin
78 rd_pointer <= 0;
79 end
80 end else begin
81 if (rd_cs && rd_en ) begin
82 rd_pointer <= rd_pointer + 1;
83 end
84 if(c==1 && wr_pointer ==rd_pointer + 1 )begin
85 rd_pointer <= rd_pointer + 1;
86 end
87 end
88 end
89
90 always @ (posedge clk or posedge rst)
91 begin : READ_DATA
92 if (rst) begin
93 data_out <= 0;
94 end else if (rd_cs && rd_en ) begin
95 data_out <= data_ram;
96 end
97 end
98
99 always @ (posedge clk or posedge rst)
100 begin : STATUS_COUNTER
101 if (rst) begin
102 status_cnt <= 0;
103 // Read but no write.
104 end else if ((rd_cs && rd_en) && !(wr_cs && wr_en)
105 && (status_cnt != 0)) begin
106 status_cnt <= status_cnt - 1;
107 // Write but no read.
108 end else if ((wr_cs && wr_en) && !(rd_cs && rd_en)
109 && (status_cnt != RAM_DEPTH)) begin
110 status_cnt <= status_cnt + 1;
111 end
112 end
113
114 ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM (
115 .address_0 (wr_pointer) , // address_0 input
116 .data_0 (data_in) , // data_0 bi-directional
117 .cs_0 (wr_cs) , // chip select
118 .we_0 (wr_en) , // write enable
119 .oe_0 (1'b0) , // output enable
120 .address_1 (rd_pointer) , // address_q input
121 .data_1 (data_ram) , // data_1 bi-directional
122 .cs_1 (rd_cs) , // chip select
123 .we_1 (1'b0) , // Read enable
124 .oe_1 (rd_en) // output enable
125 );
126
127 endmodule
128
ram_dp_ar_aw module
Code
1 //-----------------------------------------------------
2 // Design Name : ram_dp_ar_aw
3 // File Name : ram_dp_ar_aw.v
4 // Function : Asynchronous read write RAM
5 // Coder :
6 //-----------------------------------------------------
7 module ram_dp_ar_aw (
8 address_0 , // address_0 Input
9 data_0 , // data_0 bi-directional
10 cs_0 , // Chip Select
11 we_0 , // Write Enable/Read Enable
12 oe_0 , // Output Enable
13 address_1 , // address_1 Input
14 data_1 , // data_1 bi-directional
15 cs_1 , // Chip Select
16 we_1 , // Write Enable/Read Enable
17 oe_1 // Output Enable
18 );
19
20 parameter DATA_WIDTH = 8 ;
21 parameter ADDR_WIDTH = 3 ;
22 parameter RAM_DEPTH = 1 << ADDR_WIDTH;
23
24 //--------------Input Ports-----------------------
25 input [ADDR_WIDTH-1:0] address_0 ;
26 input cs_0 ;
27 input we_0 ;
28 input oe_0 ;
29 input [ADDR_WIDTH-1:0] address_1 ;
30 input cs_1 ;
31 input we_1 ;
32 input oe_1 ;
33
34 //--------------Inout Ports-----------------------
35 inout [DATA_WIDTH-1:0] data_0 ;
36 inout [DATA_WIDTH-1:0] data_1 ;
37
38 //--------------Internal variables----------------
39 reg [DATA_WIDTH-1:0] data_0_out ;
40 reg [DATA_WIDTH-1:0] data_1_out ;
41 reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
42
43 //--------------Code Starts Here------------------
44 // Memory Write Block
45 // Write Operation : When we_0 = 1, cs_0 = 1
46 always @ (/*address_0 or */cs_0 or we_0 or data_0
47 or address_1 or cs_1 or we_1 or data_1)
48 begin : MEM_WRITE
49 if ( cs_0 && we_0 ) begin
50 mem[address_0] <= data_0;
51 end else if (cs_1 && we_1) begin
52 mem[address_1] <= data_1;
53 end
54 end
55
56 // Tri-State Buffer control
57 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
58 assign data_0 = (cs_0 && oe_0 && !we_0) ? data_0_out : 8'bz;
59
60 // Memory Read Block
61 // Read Operation : When we_0 = 0, oe_0 = 1, cs_0 = 1
62 always @ (address_0 or cs_0 or we_1 or oe_0)
63 begin : MEM_READ_0
64 if (cs_0 && !we_0 && oe_0) begin
65 data_0_out <= mem[address_0];
66 end else begin
67 data_0_out <= 0;
68 end
69 end
70
71 //Second Port of RAM
72 // Tri-State Buffer control
73 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
74 assign data_1 = (cs_1 && oe_1 && !we_1) ? data_1_out : 8'bz;
75 // Memory Read Block 1
76 // Read Operation : When we_1 = 0, oe_1 = 1, cs_1 = 1
77 always @ (address_1 or cs_1 or we_1 or oe_1)
78 begin : MEM_READ_1
79 if (cs_1 && !we_1 && oe_1) begin
80 data_1_out <= mem[address_1];
81 end else begin
82 data_1_out <= 0;
83 end
84 end
85
86 endmodule // End of Module ram_dp_ar_aw
1 //-----------------------------------------------------
2 // Design Name : ram_dp_ar_aw
3 // File Name : ram_dp_ar_aw.v
4 // Function : Asynchronous read write RAM
5 // Coder :
6 //-----------------------------------------------------
7 module ram_dp_ar_aw (
8 address_0 , // address_0 Input
9 data_0 , // data_0 bi-directional
10 cs_0 , // Chip Select
11 we_0 , // Write Enable/Read Enable
12 oe_0 , // Output Enable
13 address_1 , // address_1 Input
14 data_1 , // data_1 bi-directional
15 cs_1 , // Chip Select
16 we_1 , // Write Enable/Read Enable
17 oe_1 // Output Enable
18 );
19
20 parameter DATA_WIDTH = 8 ;
21 parameter ADDR_WIDTH = 3 ;
22 parameter RAM_DEPTH = 1 << ADDR_WIDTH;
23
24 //--------------Input Ports-----------------------
25 input [ADDR_WIDTH-1:0] address_0 ;
26 input cs_0 ;
27 input we_0 ;
28 input oe_0 ;
29 input [ADDR_WIDTH-1:0] address_1 ;
30 input cs_1 ;
31 input we_1 ;
32 input oe_1 ;
33
34 //--------------Inout Ports-----------------------
35 inout [DATA_WIDTH-1:0] data_0 ;
36 inout [DATA_WIDTH-1:0] data_1 ;
37
38 //--------------Internal variables----------------
39 reg [DATA_WIDTH-1:0] data_0_out ;
40 reg [DATA_WIDTH-1:0] data_1_out ;
41 reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
42
43 //--------------Code Starts Here------------------
44 // Memory Write Block
45 // Write Operation : When we_0 = 1, cs_0 = 1
46 always @ (/*address_0 or */cs_0 or we_0 or data_0
47 or address_1 or cs_1 or we_1 or data_1)
48 begin : MEM_WRITE
49 if ( cs_0 && we_0 ) begin
50 mem[address_0] <= data_0;
51 end else if (cs_1 && we_1) begin
52 mem[address_1] <= data_1;
53 end
54 end
55
56 // Tri-State Buffer control
57 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
58 assign data_0 = (cs_0 && oe_0 && !we_0) ? data_0_out : 8'bz;
59
60 // Memory Read Block
61 // Read Operation : When we_0 = 0, oe_0 = 1, cs_0 = 1
62 always @ (address_0 or cs_0 or we_1 or oe_0)
63 begin : MEM_READ_0
64 if (cs_0 && !we_0 && oe_0) begin
65 data_0_out <= mem[address_0];
66 end else begin
67 data_0_out <= 0;
68 end
69 end
70
71 //Second Port of RAM
72 // Tri-State Buffer control
73 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
74 assign data_1 = (cs_1 && oe_1 && !we_1) ? data_1_out : 8'bz;
75 // Memory Read Block 1
76 // Read Operation : When we_1 = 0, oe_1 = 1, cs_1 = 1
77 always @ (address_1 or cs_1 or we_1 or oe_1)
78 begin : MEM_READ_1
79 if (cs_1 && !we_1 && oe_1) begin
80 data_1_out <= mem[address_1];
81 end else begin
82 data_1_out <= 0;
83 end
84 end
85
86 endmodule // End of Module ram_dp_ar_aw
Testbench
Code
1 module fifo_tb ();
2 parameter DATA_WIDTH = 8;
3 // Limit depth to 8
4 parameter ADDR_WIDTH = 3;
5
6 reg clk, rst, rd_en, wr_en,mode;
7 reg [DATA_WIDTH-1:0] data_in ;
8 wire [DATA_WIDTH-1:0] data_out ;
9 wire empty, full;
10 integer i;
11
12 initial begin
13 $monitor ("%g wr:%h wr_data:%h rd:%h rd_data:%h",
14 $time, wr_en, data_in, rd_en, data_out);
15 clk = 0;
16 rst = 0;
17 rd_en = 0;
18 wr_en = 0;
19 data_in = 0;
20 mode = 2;
21 #5 rst = 1;
22 #5 rst = 0;
23 @ (negedge clk);
24 wr_en = 1;
25 // We are causing over flow
26 for (i = 1 ; i < 11; i = i + 1) begin
27 data_in = i;
28 @ (negedge clk);
29 end
30 wr_en = 0;
31 @ (negedge clk);
32
33 rd_en = 1;
34 // We are causing under flow
35 for (i = 1 ; i < 10; i = i + 1) begin
36 @ (negedge clk);
37 end
38 wr_en = 1;
39
40 /* more
41 rd_en = 0;
42 write again
43 for (i = 1 ; i < 10; i = i + 1) begin
44 data_in = i;
45 @ (negedge clk);
46 end
47 wr_en = 0;
48 @ (negedge clk);
49 rd_en = 1;
50 read again
51 for (i = 1 ; i < 10; i = i + 1) begin
52 @ (negedge clk);
53 end */
54
55
56 rd_en = 0;
57 #100 $finish;
58 end
59
60 always #1 clk = !clk;
61
62 syn_fifo #(DATA_WIDTH,ADDR_WIDTH) fifo(
63 .clk (clk) , // Clock input
64 .rst (rst) , // Active high reset
65 .wr_cs (1'b1) , // Write chip select
66 .rd_cs (1'b1) , // Read chipe select
67 .data_in (data_in) , // Data input
68 .rd_en (rd_en) , // Read enable
69 .wr_en (wr_en) , // Write Enable
70 .data_out (data_out), // Data Output
71 .empty (empty) , // FIFO empty
72 .full (full) , // FIFO full
73 .mode (mode) // Mode
74 );
75
76 endmodule
1 module fifo_tb ();
2 parameter DATA_WIDTH = 8;
3 // Limit depth to 8
4 parameter ADDR_WIDTH = 3;
5
6 reg clk, rst, rd_en, wr_en,mode;
7 reg [DATA_WIDTH-1:0] data_in ;
8 wire [DATA_WIDTH-1:0] data_out ;
9 wire empty, full;
10 integer i;
11
12 initial begin
13 $monitor ("%g wr:%h wr_data:%h rd:%h rd_data:%h",
14 $time, wr_en, data_in, rd_en, data_out);
15 clk = 0;
16 rst = 0;
17 rd_en = 0;
18 wr_en = 0;
19 data_in = 0;
20 mode = 2;
21 #5 rst = 1;
22 #5 rst = 0;
23 @ (negedge clk);
24 wr_en = 1;
25 // We are causing over flow
26 for (i = 1 ; i < 11; i = i + 1) begin
27 data_in = i;
28 @ (negedge clk);
29 end
30 wr_en = 0;
31 @ (negedge clk);
32
33 rd_en = 1;
34 // We are causing under flow
35 for (i = 1 ; i < 10; i = i + 1) begin
36 @ (negedge clk);
37 end
38 wr_en = 1;
39
40 /* more
41 rd_en = 0;
42 write again
43 for (i = 1 ; i < 10; i = i + 1) begin
44 data_in = i;
45 @ (negedge clk);
46 end
47 wr_en = 0;
48 @ (negedge clk);
49 rd_en = 1;
50 read again
51 for (i = 1 ; i < 10; i = i + 1) begin
52 @ (negedge clk);
53 end */
54
55
56 rd_en = 0;
57 #100 $finish;
58 end
59
60 always #1 clk = !clk;
61
62 syn_fifo #(DATA_WIDTH,ADDR_WIDTH) fifo(
63 .clk (clk) , // Clock input
64 .rst (rst) , // Active high reset
65 .wr_cs (1'b1) , // Write chip select
66 .rd_cs (1'b1) , // Read chipe select
67 .data_in (data_in) , // Data input
68 .rd_en (rd_en) , // Read enable
69 .wr_en (wr_en) , // Write Enable
70 .data_out (data_out), // Data Output
71 .empty (empty) , // FIFO empty
72 .full (full) , // FIFO full
73 .mode (mode) // Mode
74 );
75
76 endmodule