Statistics
| Branch: | Tag: | Revision:

root / usrp2 / fifo / buffer_int2.v @ 4eba6ddc

History | View | Annotate | Download (4.55 KB)

1 8d6e6985 Matt Ettus
2
// FIFO Interface to the 2K buffer RAMs
3
// Read port is read-acknowledge
4
// FIXME do we want to be able to interleave reads and writes?
5
6
module buffer_int2
7
  #(parameter BASE = 0,
8
    parameter BUF_SIZE = 9)
9 1154d5be Matt Ettus
    (input clk, input rst,
10 8d6e6985 Matt Ettus
     input set_stb, input [7:0] set_addr, input [31:0] set_data,
11
     output [31:0] status,
12
13
     // Wishbone interface to RAM
14
     input wb_clk_i,
15
     input wb_rst_i,
16
     input wb_we_i,
17
     input wb_stb_i,
18
     input [15:0] wb_adr_i,
19
     input [31:0] wb_dat_i,   
20
     output [31:0] wb_dat_o,
21
     output reg wb_ack_o,
22
23
     // Write FIFO Interface
24
     input [35:0] wr_data_i,
25
     input wr_ready_i,
26
     output wr_ready_o,
27
     
28
     // Read FIFO Interface
29
     output [35:0] rd_data_o,
30
     output rd_ready_o,
31
     input rd_ready_i
32
     );
33
34 aed2e0d4 Matt Ettus
   reg [15:0]         rd_addr, wr_addr;    // Handle pkt bigger than buffer
35
   wire [15:0] 	      rd_addr_next = rd_addr + 1;
36
   reg [15:0] 	      rd_length;
37
38 8d6e6985 Matt Ettus
   wire [31:0] 	      ctrl;
39 87d57ac2 Matt Ettus
   wire 	      wr_done, wr_error, wr_idle;
40
   wire 	      rd_done, rd_error, rd_idle;
41
   wire 	      we, en, go;
42
43
   wire 	      read = ctrl[3];
44
   wire 	      rd_clear = ctrl[2];
45
   wire 	      write = ctrl[1];
46
   wire 	      wr_clear = ctrl[0];
47 8d6e6985 Matt Ettus
   
48 87d57ac2 Matt Ettus
   reg [2:0] 	      rd_state, wr_state;
49
   reg 		      rd_sop, rd_eop;
50
   wire 	      wr_sop, wr_eop;
51
   reg [1:0] 	      rd_occ;
52
   wire [1:0] 	      wr_occ;
53 8d6e6985 Matt Ettus
   
54
   localparam IDLE = 3'd0;
55
   localparam PRE_READ = 3'd1;
56
   localparam READING = 3'd2;
57
   localparam WRITING = 3'd3;
58
   localparam ERROR = 3'd4;
59
   localparam DONE = 3'd5;
60 87d57ac2 Matt Ettus
61
   // read state machine
62 8d6e6985 Matt Ettus
   always @(posedge clk)
63 87d57ac2 Matt Ettus
     if(rst | (rd_clear & go))
64 8d6e6985 Matt Ettus
       begin
65 87d57ac2 Matt Ettus
	  rd_state <= IDLE;
66 8d6e6985 Matt Ettus
	  rd_sop <= 0;
67
	  rd_eop <= 0;
68
	  rd_occ <= 0;
69
       end
70
     else
71 87d57ac2 Matt Ettus
       case(rd_state)
72
	 IDLE :
73
	   if(go & read)
74 8d6e6985 Matt Ettus
	     begin
75 87d57ac2 Matt Ettus
		rd_addr <= 0;
76
		rd_state <= PRE_READ;
77 aed2e0d4 Matt Ettus
		rd_length <= ctrl[31:16];
78 8d6e6985 Matt Ettus
	     end
79 87d57ac2 Matt Ettus
	 
80
	 PRE_READ :
81
	   begin
82
	      rd_state <= READING;
83 17450097 Josh Blum
	      rd_addr <= rd_addr_next;
84 87d57ac2 Matt Ettus
	      rd_occ <= 2'b00;
85
	      rd_sop <= 1;
86
	      rd_eop <= 0;
87
	   end
88
	 
89
	 READING :
90
	   if(rd_ready_i)
91 8d6e6985 Matt Ettus
	     begin
92 87d57ac2 Matt Ettus
		rd_sop <= 0;
93 17450097 Josh Blum
		rd_addr <= rd_addr_next;
94
		if(rd_addr_next == rd_length)
95 8d6e6985 Matt Ettus
		  begin
96 87d57ac2 Matt Ettus
		     rd_eop <= 1;
97
		     // FIXME assign occ here
98
		     rd_occ <= 0;
99
		  end
100
		else
101
		  rd_eop <= 0;
102
		if(rd_eop)
103
		  rd_state <= DONE;
104
	     end
105
	 
106
       endcase // case(rd_state)
107
   
108
   // write state machine
109
   always @(posedge clk)
110 35ae7bc8 Josh Blum
     if(rst | (wr_clear & go))
111 87d57ac2 Matt Ettus
       wr_state <= IDLE;
112
     else 
113
       case(wr_state)
114
	 IDLE :
115
	   if(go & write)
116
	     begin
117
		wr_addr <= 0;
118
		wr_state <= WRITING;
119
	     end
120
	 
121
	 WRITING :
122
	   if(wr_ready_i)
123
	     begin
124
		wr_addr <= wr_addr + 1;
125
		if(wr_sop & wr_eop)
126
		  wr_state <= ERROR;  // Should save OCC flags here
127
		else if(wr_eop)
128
		  wr_state <= DONE;
129
	     end // if (wr_ready_i)
130
       endcase // case(wr_state)
131 8d6e6985 Matt Ettus
   
132
   assign     rd_data_o[35:32] = { rd_occ[1:0], rd_eop, rd_sop };
133 87d57ac2 Matt Ettus
   assign     rd_ready_o = (rd_state == READING);
134 8d6e6985 Matt Ettus
   
135
   assign     wr_sop = wr_data_i[32];
136
   assign     wr_eop = wr_data_i[33];
137
   assign     wr_occ = wr_data_i[35:34];
138 87d57ac2 Matt Ettus
   assign     wr_ready_o = (wr_state == WRITING);
139 8d6e6985 Matt Ettus
140 87d57ac2 Matt Ettus
   assign     we = (wr_state == WRITING); // always write to avoid timing issue
141
   assign     en = ~((rd_state==READING)& ~rd_ready_i);   // FIXME potential critical path
142 8d6e6985 Matt Ettus
   
143 87d57ac2 Matt Ettus
   assign     rd_done = (rd_state == DONE);
144
   assign     wr_done = (wr_state == DONE);
145
   assign     rd_error = (rd_state == ERROR);
146
   assign     wr_error = (wr_state == ERROR);
147
   assign     rd_idle = (rd_state == IDLE);
148
   assign     wr_idle = (wr_state == IDLE);
149 8d6e6985 Matt Ettus
150 aed2e0d4 Matt Ettus
   wire [BUF_SIZE-1:0] wr_addr_clip = (|wr_addr[15:BUF_SIZE]) ? {BUF_SIZE{1'b1}} : wr_addr[BUF_SIZE-1:0];
151
   
152 87d57ac2 Matt Ettus
   ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer_in // CPU reads here
153
     (.clka(wb_clk_i),.ena(wb_stb_i),.wea(1'b0),
154
      .addra(wb_adr_i[BUF_SIZE+1:2]),.dia(0),.doa(wb_dat_o),
155
      .clkb(clk),.enb(1'b1),.web(we),
156 aed2e0d4 Matt Ettus
      .addrb(wr_addr_clip),.dib(wr_data_i[31:0]),.dob());
157 87d57ac2 Matt Ettus
   
158
   ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer_out // CPU writes here
159 8d6e6985 Matt Ettus
     (.clka(wb_clk_i),.ena(wb_stb_i),.wea(wb_we_i),
160 87d57ac2 Matt Ettus
      .addra(wb_adr_i[BUF_SIZE+1:2]),.dia(wb_dat_i),.doa(),
161
      .clkb(clk),.enb(en),.web(1'b0),
162 aed2e0d4 Matt Ettus
      .addrb(rd_addr[BUF_SIZE-1:0]),.dib(0),.dob(rd_data_o[31:0]));
163 8d6e6985 Matt Ettus
   
164
   always @(posedge wb_clk_i)
165
     if(wb_rst_i)
166
       wb_ack_o <= 0;
167
     else
168
       wb_ack_o <= wb_stb_i & ~wb_ack_o;
169
170
   setting_reg #(.my_addr(BASE)) 
171
   sreg(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),.in(set_data),
172
	.out(ctrl),.changed(go));
173
   
174 aed2e0d4 Matt Ettus
   assign status = { wr_addr,
175 87d57ac2 Matt Ettus
		     8'b0,1'b0,rd_idle,rd_error,rd_done, 1'b0,wr_idle,wr_error,wr_done};
176 8d6e6985 Matt Ettus
177
endmodule // buffer_int2