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 FIFO interface of Buffer Pool
13 output [31:0] wr_dat_o,
14 output [3:0] wr_flags_o,
24 output [15:0] fifo_occupied,
29 output [31:0] debug_rx
32 wire [31:0] new_time, new_command;
33 wire sc_pre1, clear_overrun;
34 wire [31:0] rcvtime_pre;
36 wire [8:0] lines_per_frame;
38 wire send_imm_pre, chain_pre;
40 wire full_ctrl, read_ctrl, empty_ctrl, write_ctrl;
42 setting_reg #(.my_addr(`DSP_CORE_RX_BASE+3)) sr_3
43 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
44 .in(set_data),.out(new_time),.changed(sc_pre1));
46 setting_reg #(.my_addr(`DSP_CORE_RX_BASE+4)) sr_4
47 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
48 .in(set_data),.out(new_command),.changed());
50 setting_reg #(.my_addr(`DSP_CORE_RX_BASE+5)) sr_5
51 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
52 .in(set_data),.out(),.changed(clear_overrun));
57 assign write_ctrl = sc_pre1 & ~sc_pre2;
59 shortfifo #(.WIDTH(64)) commandfifo
60 (.clk(clk),.rst(rst),.clear(clear_overrun),
61 .datain({new_command,new_time}), .write(write_ctrl), .full(full_ctrl),
62 .dataout({send_imm_pre,chain_pre,numlines,lines_per_frame,rcvtime_pre}),
63 .read(read_ctrl), .empty(empty_ctrl) );
65 // Buffer interface to internal FIFO
66 wire have_space, write;
67 wire [35:0] fifo_line;
69 // Internal FIFO, size 9 is 2K, size 10 is 4K
70 fifo_cascade #(.WIDTH(36),.SIZE(FIFOSIZE)) rxfifo
71 (.clk(clk),.reset(rst),.clear(clear_overrun),
72 .datain(fifo_line), .src_rdy_i(write), .dst_rdy_o(have_space),
73 .dataout({wr_flags_o,wr_dat_o}), .src_rdy_o(wr_ready_o), .dst_rdy_i(wr_ready_i),
74 .space(),.occupied(fifo_occupied) );
75 assign fifo_full = ~have_space;
76 assign fifo_empty = ~wr_ready_o;
78 // Internal FIFO to DSP interface
79 reg [22:0] lines_left;
80 reg [8:0] lines_left_frame;
81 localparam IBS_IDLE = 0;
82 localparam IBS_WAITING = 1;
83 localparam IBS_FIRSTLINE = 2;
84 localparam IBS_RUNNING = 3;
85 localparam IBS_OVERRUN = 4;
89 wire [32:0] delta_time = {1'b0,rcvtime}-{1'b0,master_time};
90 wire too_late = (delta_time[32:31] == 2'b11) & ~send_imm;
91 wire go_now = send_imm | ( master_time == rcvtime );
96 ibs_state <= IBS_IDLE;
98 lines_left_frame <= 0;
106 ibs_state <= IBS_IDLE;
108 lines_left_frame <= 0;
118 lines_left <= numlines;
119 lines_left_frame <= lines_per_frame;
120 rcvtime <= rcvtime_pre;
121 ibs_state <= IBS_WAITING;
122 send_imm <= send_imm_pre;
127 ibs_state <= IBS_FIRSTLINE;
129 ibs_state <= IBS_OVERRUN;
131 if(~have_space | strobe)
132 ibs_state <= IBS_OVERRUN;
134 ibs_state <= IBS_RUNNING;
138 ibs_state <= IBS_OVERRUN;
141 lines_left <= lines_left - 1;
144 ibs_state <= IBS_IDLE;
146 ibs_state <= IBS_OVERRUN;
149 lines_left <= numlines;
150 lines_left_frame <= lines_per_frame;
151 rcvtime <= rcvtime_pre;
152 ibs_state <= IBS_FIRSTLINE;
153 send_imm <= send_imm_pre;
156 else if(lines_left_frame == 1)
158 lines_left_frame <= lines_per_frame;
159 ibs_state <= IBS_FIRSTLINE;
162 lines_left_frame <= lines_left_frame - 1;
163 end // else: !if(~have_space)
164 endcase // case(ibs_state)
166 assign fifo_line = (ibs_state == IBS_FIRSTLINE) ? {2'b0,1'b0,1'b1,master_time} :
167 {2'b0,((lines_left==1)|(lines_left_frame==1)),1'b0,sample};
169 assign write = ((ibs_state == IBS_FIRSTLINE) | strobe) & have_space; // & (ibs_state == IBS_RUNNING) should strobe only when running
170 assign overrun = (ibs_state == IBS_OVERRUN);
171 assign run = (ibs_state == IBS_RUNNING) | (ibs_state == IBS_FIRSTLINE);
172 assign read_ctrl = ( (ibs_state == IBS_IDLE) |
173 ((ibs_state == IBS_RUNNING) & strobe & have_space & (lines_left==1) & chain) )
176 assign debug_rx = { 8'd0,
177 1'd0, send_imm, chain, wr_ready_i,wr_ready_o, 2'b0, run,
178 write,have_space,wr_flags_o[1:0],write_ctrl,full_ctrl,read_ctrl,empty_ctrl,
179 sc_pre1, clear_overrun, go_now, too_late, overrun, ibs_state[2:0] };
180 endmodule // rx_control