2 `define DSP_CORE_RX_BASE 160
5 #(parameter FIFOSIZE = 10)
7 input set_stb, input [7:0] set_addr, input [31:0] set_data,
9 input [31:0] master_time,
12 // To Buffer interface
13 output [31:0] wr_dat_o,
27 output [15:0] fifo_occupied,
32 output [31:0] debug_rx
35 wire [31:0] new_time, new_command;
36 wire sc_pre1, clear_overrun;
37 wire [31:0] rcvtime_pre;
39 wire [8:0] lines_per_frame;
41 wire send_imm_pre, chain_pre;
43 wire full_ctrl, read_ctrl, empty_ctrl, write_ctrl;
45 setting_reg #(.my_addr(`DSP_CORE_RX_BASE+3)) sr_3
46 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
47 .in(set_data),.out(new_time),.changed(sc_pre1));
49 setting_reg #(.my_addr(`DSP_CORE_RX_BASE+4)) sr_4
50 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
51 .in(set_data),.out(new_command),.changed());
53 setting_reg #(.my_addr(`DSP_CORE_RX_BASE+5)) sr_5
54 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
55 .in(set_data),.out(),.changed(clear_overrun));
60 assign write_ctrl = sc_pre1 & ~sc_pre2;
62 shortfifo #(.WIDTH(64)) commandfifo
63 (.clk(clk),.rst(rst),.clear(clear_overrun),
64 .datain({new_command,new_time}), .write(write_ctrl), .full(full_ctrl),
65 .dataout({send_imm_pre,chain_pre,numlines,lines_per_frame,rcvtime_pre}),
66 .read(read_ctrl), .empty(empty_ctrl) );
68 // Buffer interface to internal FIFO
69 wire write, full, read, empty;
73 localparam XFER_IDLE = 1'b0;
74 localparam XFER_GO = 1'b1;
78 xfer_state <= XFER_IDLE;
81 xfer_state <= XFER_IDLE;
86 xfer_state <= XFER_GO;
88 if((eop_o | wr_full_i) & wr_write_o)
89 xfer_state <= XFER_IDLE;
91 xfer_state <= XFER_IDLE;
92 endcase // case(xfer_state)
94 assign wr_write_o = (xfer_state == XFER_GO) & ~empty;
95 assign wr_done_o = (eop_o & wr_write_o);
96 assign wr_error_o = 0; // FIXME add check here for eop if we have wr_full_i once we have IBS
98 assign read = wr_write_o | (~empty & ~sop_o); // FIXME what if there is junk between packets?
100 wire [33:0] fifo_line;
102 // Internal FIFO, size 9 is 2K, size 10 is 4K
103 cascadefifo2 #(.WIDTH(34),.SIZE(FIFOSIZE)) rxfifo
104 (.clk(clk),.rst(rst),.clear(clear_overrun),
105 .datain(fifo_line), .write(write), .full(full),
106 .dataout({sop_o,eop_o,wr_dat_o}), .read(read), .empty(empty),
107 .space(),.occupied(fifo_occupied) );
108 assign fifo_full = full;
109 assign fifo_empty = empty;
111 // Internal FIFO to DSP interface
112 reg [22:0] lines_left;
113 reg [8:0] lines_left_frame;
114 localparam IBS_IDLE = 0;
115 localparam IBS_WAITING = 1;
116 localparam IBS_FIRSTLINE = 2;
117 localparam IBS_RUNNING = 3;
118 localparam IBS_OVERRUN = 4;
122 wire [32:0] delta_time = {1'b0,rcvtime}-{1'b0,master_time};
123 wire too_late = (delta_time[32:31] == 2'b11) & ~send_imm;
124 wire go_now = send_imm | ( master_time == rcvtime );
126 always @(posedge clk)
129 ibs_state <= IBS_IDLE;
131 lines_left_frame <= 0;
139 ibs_state <= IBS_IDLE;
141 lines_left_frame <= 0;
151 lines_left <= numlines;
152 lines_left_frame <= lines_per_frame;
153 rcvtime <= rcvtime_pre;
154 ibs_state <= IBS_WAITING;
155 send_imm <= send_imm_pre;
160 ibs_state <= IBS_FIRSTLINE;
162 ibs_state <= IBS_OVERRUN;
165 ibs_state <= IBS_OVERRUN;
167 ibs_state <= IBS_RUNNING;
171 ibs_state <= IBS_OVERRUN;
174 lines_left <= lines_left - 1;
177 ibs_state <= IBS_IDLE;
179 ibs_state <= IBS_OVERRUN;
182 lines_left <= numlines;
183 lines_left_frame <= lines_per_frame;
184 rcvtime <= rcvtime_pre;
185 ibs_state <= IBS_FIRSTLINE;
186 send_imm <= send_imm_pre;
189 else if(lines_left_frame == 1)
191 lines_left_frame <= lines_per_frame;
192 ibs_state <= IBS_FIRSTLINE;
195 lines_left_frame <= lines_left_frame - 1;
196 end // else: !if(full)
197 endcase // case(ibs_state)
199 assign fifo_line = (ibs_state == IBS_FIRSTLINE) ? {1'b1,1'b0,master_time} :
200 {1'b0,((lines_left==1)|(lines_left_frame==1)),sample};
202 assign write = ((ibs_state == IBS_FIRSTLINE) | strobe) & ~full; // & (ibs_state == IBS_RUNNING) should strobe only when running
203 assign overrun = (ibs_state == IBS_OVERRUN);
204 assign run = (ibs_state == IBS_RUNNING) | (ibs_state == IBS_FIRSTLINE);
205 assign read_ctrl = ( (ibs_state == IBS_IDLE) |
206 ((ibs_state == IBS_RUNNING) & strobe & ~full & (lines_left==1) & chain) )
209 assign debug_rx = { 6'd0,send_imm,chain,
210 wr_write_o, wr_done_o, wr_ready_i, wr_full_i,xfer_state,eop_o, sop_o, run,
211 write,full,read,empty,write_ctrl,full_ctrl,read_ctrl,empty_ctrl,
212 sc_pre1, clear_overrun, go_now, too_late, overrun, ibs_state[2:0] };
213 endmodule // rx_control