Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / inband_lib / channel_ram.v
1 module channel_ram 
2    ( // System
3      input txclk, input reset,
4      // USB side
5      input [31:0] datain, input WR, input WR_done, output have_space,
6      // Reader side 
7      output [31:0] dataout, input RD, input RD_done, output packet_waiting);
8         
9    reg [6:0] wr_addr, rd_addr;
10    reg [1:0] which_ram_wr, which_ram_rd;
11    reg [2:0] nb_packets;
12         
13    reg [31:0] ram0 [0:127];
14    reg [31:0] ram1 [0:127];
15    reg [31:0] ram2 [0:127];
16    reg [31:0] ram3 [0:127];
17         
18    reg [31:0] dataout0;
19    reg [31:0] dataout1;
20    reg [31:0] dataout2;
21    reg [31:0] dataout3;
22         
23    wire wr_done_int;
24    wire rd_done_int;
25    wire [6:0] rd_addr_final;
26    wire [1:0] which_ram_rd_final;
27         
28    // USB side
29    always @(posedge txclk)
30        if(WR & (which_ram_wr == 2'd0)) ram0[wr_addr] <= datain;
31                         
32    always @(posedge txclk)
33        if(WR & (which_ram_wr == 2'd1)) ram1[wr_addr] <= datain;
34
35    always @(posedge txclk)
36        if(WR & (which_ram_wr == 2'd2)) ram2[wr_addr] <= datain;
37
38    always @(posedge txclk)
39        if(WR & (which_ram_wr == 2'd3)) ram3[wr_addr] <= datain;
40
41    assign wr_done_int = ((WR && (wr_addr == 7'd127)) || WR_done);
42    
43    always @(posedge txclk)
44        if(reset)
45            wr_addr <= 0;
46        else if (WR_done)
47            wr_addr <= 0;
48        else if (WR) 
49            wr_addr <= wr_addr + 7'd1;
50                 
51    always @(posedge txclk)
52       if(reset)
53           which_ram_wr <= 0;
54       else if (wr_done_int) 
55           which_ram_wr <= which_ram_wr + 2'd1;
56         
57    assign have_space = (nb_packets < 3'd3);
58                 
59    // Reader side
60    // short hand fifo
61    // rd_addr_final is what rd_addr is going to be next clock cycle
62    // which_ram_rd_final is what which_ram_rd is going to be next clock cycle
63    always @(posedge txclk)  dataout0 <= ram0[rd_addr_final];
64    always @(posedge txclk)  dataout1 <= ram1[rd_addr_final];
65    always @(posedge txclk)  dataout2 <= ram2[rd_addr_final];
66    always @(posedge txclk)  dataout3 <= ram3[rd_addr_final];
67         
68    assign dataout = (which_ram_rd_final[1]) ? 
69                     (which_ram_rd_final[0] ? dataout3 : dataout2) :
70                     (which_ram_rd_final[0] ? dataout1 : dataout0);
71
72    //RD_done is the only way to signal the end of one packet
73    assign rd_done_int = RD_done;   
74
75    always @(posedge txclk)
76        if (reset)
77            rd_addr <= 0;
78        else if (RD_done)
79            rd_addr <= 0;
80        else if (RD) 
81            rd_addr <= rd_addr + 7'd1;
82                         
83    assign rd_addr_final = (reset|RD_done) ? (6'd0) : 
84                           ((RD)?(rd_addr+7'd1):rd_addr); 
85         
86    always @(posedge txclk)
87        if (reset)
88            which_ram_rd <= 0;
89        else if (rd_done_int)
90            which_ram_rd <= which_ram_rd + 2'd1;
91
92    assign which_ram_rd_final = (reset) ? (2'd0):
93                                ((rd_done_int) ? (which_ram_rd + 2'd1) : which_ram_rd);
94                                 
95    //packet_waiting is set to zero if rd_done_int is high
96    //because there is no guarantee that nb_packets will be pos.
97
98    assign packet_waiting = (nb_packets > 1) | ((nb_packets == 1)&(~rd_done_int));
99    always @(posedge txclk)
100        if (reset)
101            nb_packets <= 0;
102        else if (wr_done_int & ~rd_done_int)
103            nb_packets <= nb_packets + 3'd1;
104        else if (rd_done_int & ~wr_done_int)
105            nb_packets <= nb_packets - 3'd1;
106                         
107 endmodule