Statistics
| Branch: | Tag: | Revision:

root / usrp2 / sdr_lib / rx_control.v @ bfaa5d14

History | View | Annotate | Download (5.94 KB)

1
//
2
// Copyright 2011 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18

    
19
`define DSP_CORE_RX_BASE 160
20

    
21
module rx_control
22
  #(parameter FIFOSIZE = 10)
23
    (input clk, input rst,
24
     input set_stb, input [7:0] set_addr, input [31:0] set_data,
25
     
26
     input [31:0] master_time,
27
     output overrun,
28
     
29
     // To FIFO interface of Buffer Pool
30
     output [31:0] wr_dat_o,
31
     output [3:0] wr_flags_o,
32
     input wr_ready_i,
33
     output wr_ready_o,
34

    
35
     // From DSP Core
36
     input [31:0] sample,
37
     output run,
38
     input strobe,
39

    
40
     // FIFO Levels
41
     output [15:0] fifo_occupied,
42
     output fifo_full,
43
     output fifo_empty,
44
     
45
     // Debug
46
     output [31:0] debug_rx
47
     );
48

    
49
   wire [31:0] 	   new_time, new_command;
50
   wire 	   sc_pre1, clear_overrun;
51
   wire [31:0] 	   rcvtime_pre;
52
   reg [31:0] 	   rcvtime;
53
   wire [8:0] 	   lines_per_frame;
54
   wire [20:0] 	   numlines;
55
   wire 	   send_imm_pre, chain_pre;
56
   reg 		   send_imm, chain;
57
   wire 	   full_ctrl, read_ctrl, empty_ctrl, write_ctrl;
58

    
59
   setting_reg #(.my_addr(`DSP_CORE_RX_BASE+3)) sr_3
60
     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
61
      .in(set_data),.out(new_time),.changed(sc_pre1));
62
   
63
   setting_reg #(.my_addr(`DSP_CORE_RX_BASE+4)) sr_4
64
     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
65
      .in(set_data),.out(new_command),.changed());
66

    
67
   setting_reg #(.my_addr(`DSP_CORE_RX_BASE+5)) sr_5
68
     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
69
      .in(set_data),.out(),.changed(clear_overrun));
70

    
71
   reg 	       sc_pre2;
72
   always @(posedge clk)
73
     sc_pre2 <= sc_pre1;
74
   assign      write_ctrl = sc_pre1 & ~sc_pre2;
75
   
76
   shortfifo #(.WIDTH(64)) commandfifo
77
     (.clk(clk),.rst(rst),.clear(clear_overrun),
78
      .datain({new_command,new_time}), .write(write_ctrl), .full(full_ctrl),
79
      .dataout({send_imm_pre,chain_pre,numlines,lines_per_frame,rcvtime_pre}), 
80
      .read(read_ctrl), .empty(empty_ctrl) );
81

    
82
   // Buffer interface to internal FIFO
83
   wire        have_space, write;
84
   wire [35:0] fifo_line;
85
   
86
   // Internal FIFO, size 9 is 2K, size 10 is 4K
87
   fifo_cascade #(.WIDTH(36),.SIZE(FIFOSIZE)) rxfifo
88
     (.clk(clk),.reset(rst),.clear(clear_overrun),
89
      .datain(fifo_line), .src_rdy_i(write), .dst_rdy_o(have_space),
90
      .dataout({wr_flags_o,wr_dat_o}), .src_rdy_o(wr_ready_o), .dst_rdy_i(wr_ready_i),
91
      .space(),.occupied(fifo_occupied) );
92
   assign      fifo_full = ~have_space;
93
   assign      fifo_empty = ~wr_ready_o;
94

    
95
   // Internal FIFO to DSP interface
96
   reg [22:0] lines_left;
97
   reg [8:0]  lines_left_frame;
98
   localparam IBS_IDLE = 0;
99
   localparam IBS_WAITING = 1;
100
   localparam IBS_FIRSTLINE = 2;
101
   localparam IBS_RUNNING = 3;
102
   localparam IBS_OVERRUN = 4;
103
   
104
   reg [2:0] ibs_state;
105
  
106
   wire [32:0] delta_time = {1'b0,rcvtime}-{1'b0,master_time};
107
   wire        too_late = (delta_time[32:31] == 2'b11) & ~send_imm;
108
   wire        go_now = send_imm | ( master_time == rcvtime );
109
 
110
   always @(posedge clk)
111
     if(rst)
112
       begin
113
	  ibs_state <= IBS_IDLE;
114
	  lines_left <= 0;
115
	  lines_left_frame <= 0;
116
	  rcvtime <= 0;
117
	  send_imm <= 0;
118
	  chain <= 0;
119
       end
120
     else
121
       if(clear_overrun)
122
	 begin
123
	  ibs_state <= IBS_IDLE;
124
	  lines_left <= 0;
125
	  lines_left_frame <= 0;
126
	  rcvtime <= 0;
127
	  send_imm <= 0;
128
	  chain <= 0;
129
	 end
130
       else 
131
	 case(ibs_state)
132
	   IBS_IDLE :
133
	     if(~empty_ctrl)
134
	       begin
135
		  lines_left <= numlines;
136
		  lines_left_frame <= lines_per_frame;
137
		  rcvtime <= rcvtime_pre;
138
		  ibs_state <= IBS_WAITING;
139
		  send_imm <= send_imm_pre;
140
		  chain <= chain_pre;
141
	       end
142
	   IBS_WAITING :
143
	     if(go_now)
144
	       ibs_state <= IBS_FIRSTLINE;
145
	     else if(too_late)
146
	       ibs_state <= IBS_OVERRUN;
147
	   IBS_FIRSTLINE :
148
	     if(~have_space | strobe)
149
	       ibs_state <= IBS_OVERRUN;
150
	     else
151
	       ibs_state <= IBS_RUNNING;
152
	   IBS_RUNNING :
153
	     if(strobe)
154
	       if(~have_space)
155
		 ibs_state <= IBS_OVERRUN;
156
	       else
157
		 begin
158
		    lines_left <= lines_left - 1;
159
		    if(lines_left == 1)
160
		      if(~chain)
161
			ibs_state <= IBS_IDLE;
162
		      else if(empty_ctrl)
163
			ibs_state <= IBS_OVERRUN;
164
		      else
165
			begin
166
			   lines_left <= numlines;
167
			   lines_left_frame <= lines_per_frame;
168
			   rcvtime <= rcvtime_pre;
169
			   ibs_state <= IBS_FIRSTLINE;
170
			   send_imm <= send_imm_pre;
171
			   chain <= chain_pre;
172
			end
173
		    else if(lines_left_frame == 1)
174
		      begin
175
			 lines_left_frame <= lines_per_frame;
176
			 ibs_state <= IBS_FIRSTLINE;
177
		      end
178
		    else
179
		      lines_left_frame <= lines_left_frame - 1;
180
		 end // else: !if(~have_space)
181
	 endcase // case(ibs_state)
182
   
183
   assign fifo_line = (ibs_state == IBS_FIRSTLINE) ? {2'b0,1'b0,1'b1,master_time} :
184
		      {2'b0,((lines_left==1)|(lines_left_frame==1)),1'b0,sample};
185
   
186
   assign write = ((ibs_state == IBS_FIRSTLINE) | strobe) & have_space;  // & (ibs_state == IBS_RUNNING) should strobe only when running
187
   assign overrun = (ibs_state == IBS_OVERRUN);
188
   assign run = (ibs_state == IBS_RUNNING) | (ibs_state == IBS_FIRSTLINE);
189
   assign read_ctrl = ( (ibs_state == IBS_IDLE) | 
190
			((ibs_state == IBS_RUNNING) & strobe & have_space & (lines_left==1) & chain) )
191
	  & ~empty_ctrl;
192
   
193
   assign debug_rx = { 8'd0,
194
		       1'd0, send_imm, chain, wr_ready_i,wr_ready_o, 2'b0, run,
195
		       write,have_space,wr_flags_o[1:0],write_ctrl,full_ctrl,read_ctrl,empty_ctrl,
196
		       sc_pre1, clear_overrun, go_now, too_late, overrun, ibs_state[2:0] };
197
endmodule // rx_control