2 `define DSP_CORE_TX_BASE 128
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 input [31:0] rd_dat_i,
26 output [15:0] fifo_occupied,
34 // Buffer interface to internal FIFO
35 wire write_data, write_ctrl, full_data, full_ctrl;
36 wire read_data, read_ctrl, empty_data, empty_ctrl;
41 localparam XFER_IDLE = 0;
42 localparam XFER_1 = 1;
43 localparam XFER_2 = 2;
44 localparam XFER_DATA = 3;
48 xfer_state <= XFER_IDLE;
51 xfer_state <= XFER_IDLE;
60 held_flags <= rd_dat_i[2:0];
64 xfer_state <= XFER_DATA;
66 if(rd_eop_i & ~full_data)
67 xfer_state <= XFER_IDLE;
68 endcase // case(xfer_state)
70 assign write_data = (xfer_state == XFER_DATA) & ~full_data;
71 assign write_ctrl = (xfer_state == XFER_2) & ~full_ctrl;
73 assign rd_read_o = (xfer_state == XFER_1) | write_data | write_ctrl;
74 assign rd_done_o = 0; // Always take everything we're given
75 assign rd_error_o = 0; // Should we indicate overruns here?
78 wire sop_o, eop_o, eob, sob, send_imm;
82 cascadefifo2 #(.WIDTH(34),.SIZE(FIFOSIZE)) txctrlfifo
83 (.clk(clk),.rst(rst),.clear(clear_state),
84 .datain({rd_sop_i,rd_eop_i,rd_dat_i}), .write(write_data), .full(full_data),
85 .dataout({sop_o,eop_o,data_o}), .read(read_data), .empty(empty_data),
86 .space(), .occupied(fifo_occupied) );
87 assign fifo_full = full_data;
88 assign fifo_empty = empty_data;
90 shortfifo #(.WIDTH(35)) ctrlfifo
91 (.clk(clk),.rst(rst),.clear(clear_state),
92 .datain({held_flags[2:0],rd_dat_i}), .write(write_ctrl), .full(full_ctrl),
93 .dataout({send_imm,sob,eob,sendtime}), .read(read_ctrl), .empty(empty_ctrl),
94 .space(), .occupied(occ_ctrl) );
96 // Internal FIFO to DSP interface
99 localparam IBS_IDLE = 0;
100 localparam IBS_WAIT = 1;
101 localparam IBS_RUNNING = 2;
102 localparam IBS_CONT_BURST = 3;
103 localparam IBS_UNDERRUN = 7;
105 wire [32:0] delta_time = {1'b0,sendtime}-{1'b0,master_time};
107 wire too_late = (delta_time[32:31] == 2'b11);
108 wire go_now = ( master_time == sendtime );
110 always @(posedge clk)
112 ibs_state <= IBS_IDLE;
116 if(~empty_ctrl & ~empty_data)
117 ibs_state <= IBS_WAIT;
120 ibs_state <= IBS_RUNNING;
122 ibs_state <= IBS_UNDERRUN;
124 ibs_state <= IBS_RUNNING;
128 ibs_state <= IBS_UNDERRUN;
131 ibs_state <= IBS_IDLE;
133 ibs_state <= IBS_CONT_BURST;
135 if(~empty_ctrl) // & ~empty_data)
136 ibs_state <= IBS_RUNNING;
138 ibs_state <= IBS_UNDERRUN;
139 IBS_UNDERRUN : // FIXME Should probably clean everything out
141 ibs_state <= IBS_IDLE;
142 endcase // case(ibs_state)
144 assign read_ctrl = (ibs_state == IBS_RUNNING) & strobe & eop_o; // & ~empty_ctrl;
145 assign read_data = (ibs_state == IBS_RUNNING) & strobe & ~empty_data;
146 assign run = (ibs_state == IBS_RUNNING) | (ibs_state == IBS_CONT_BURST);
147 assign underrun = (ibs_state == IBS_UNDERRUN);
149 wire [7:0] interp_rate;
150 setting_reg #(.my_addr(`DSP_CORE_TX_BASE+3)) sr_3
151 (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
152 .in(set_data),.out(),.changed(clear_state));
154 assign sample = data_o;
156 assign debug = { {16'b0},
157 { read_data, write_data, read_ctrl, write_ctrl, xfer_state[1:0],full_ctrl,empty_ctrl },
158 { occ_ctrl, eop_o, clear_state, underrun} };
160 endmodule // tx_control