root / usrp2 / vrt / vita_rx_framer.v @ 4f79676f
History | View | Annotate | Download (7.6 kB)
| 1 |
|
|---|---|
| 2 |
module vita_rx_framer |
| 3 |
#(parameter BASE=0, |
| 4 |
parameter MAXCHAN=1) |
| 5 |
(input clk, input reset, input clear, |
| 6 |
input set_stb, input [7:0] set_addr, input [31:0] set_data, |
| 7 |
|
| 8 |
// To FIFO interface of Buffer Pool |
| 9 |
output [35:0] data_o, |
| 10 |
input dst_rdy_i, |
| 11 |
output src_rdy_o, |
| 12 |
|
| 13 |
// From vita_rx_control |
| 14 |
input [4+64+(32*MAXCHAN)-1:0] sample_fifo_i, |
| 15 |
input sample_fifo_src_rdy_i, |
| 16 |
output sample_fifo_dst_rdy_o, |
| 17 |
|
| 18 |
// FIFO Levels |
| 19 |
output [15:0] fifo_occupied, |
| 20 |
output fifo_full, |
| 21 |
output fifo_empty, |
| 22 |
|
| 23 |
output [31:0] debug_rx |
| 24 |
); |
| 25 |
|
| 26 |
localparam SAMP_WIDTH = 4+64+(32*MAXCHAN); |
| 27 |
reg [3:0] sample_phase; |
| 28 |
wire [3:0] numchan; |
| 29 |
wire [3:0] flags_fifo_o = sample_fifo_i[SAMP_WIDTH-1:SAMP_WIDTH-4]; |
| 30 |
wire [63:0] vita_time_fifo_o = sample_fifo_i[SAMP_WIDTH-5:SAMP_WIDTH-68]; |
| 31 |
|
| 32 |
reg [31:0] data_fifo_o; |
| 33 |
|
| 34 |
// The tools won't synthesize properly without this kludge because of the variable |
| 35 |
// parameter length |
| 36 |
|
| 37 |
wire [127:0] FIXED_WIDTH_KLUDGE = sample_fifo_i; |
| 38 |
always @* |
| 39 |
case(sample_phase) |
| 40 |
4'd0 : data_fifo_o = FIXED_WIDTH_KLUDGE[31:0]; |
| 41 |
4'd1 : data_fifo_o = FIXED_WIDTH_KLUDGE[63:32]; |
| 42 |
4'd2 : data_fifo_o = FIXED_WIDTH_KLUDGE[95:64]; |
| 43 |
4'd3 : data_fifo_o = FIXED_WIDTH_KLUDGE[127:96]; |
| 44 |
default : data_fifo_o = 32'hDEADBEEF; |
| 45 |
endcase // case (sample_phase) |
| 46 |
|
| 47 |
wire clear_pkt_count, pkt_fifo_rdy, sample_fifo_in_rdy; |
| 48 |
|
| 49 |
wire [31:0] vita_header, vita_streamid, vita_trailer; |
| 50 |
wire [15:0] samples_per_packet; |
| 51 |
|
| 52 |
reg [33:0] pkt_fifo_line; |
| 53 |
reg [3:0] vita_state; |
| 54 |
reg [15:0] sample_ctr; |
| 55 |
reg [3:0] pkt_count; |
| 56 |
|
| 57 |
wire [15:0] vita_pkt_len = samples_per_packet + 6; |
| 58 |
//wire [3:0] flags = {signal_overrun,signal_brokenchain,signal_latecmd,signal_cmd_done};
|
| 59 |
|
| 60 |
wire clear_reg; |
| 61 |
wire clear_int = clear | clear_reg; |
| 62 |
|
| 63 |
setting_reg #(.my_addr(BASE+3)) sr_clear |
| 64 |
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), |
| 65 |
.in(set_data),.out(),.changed(clear_reg)); |
| 66 |
|
| 67 |
setting_reg #(.my_addr(BASE+4)) sr_header |
| 68 |
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), |
| 69 |
.in(set_data),.out(vita_header),.changed()); |
| 70 |
|
| 71 |
setting_reg #(.my_addr(BASE+5)) sr_streamid |
| 72 |
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), |
| 73 |
.in(set_data),.out(vita_streamid),.changed(clear_pkt_count)); |
| 74 |
|
| 75 |
setting_reg #(.my_addr(BASE+6)) sr_trailer |
| 76 |
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), |
| 77 |
.in(set_data),.out(vita_trailer),.changed()); |
| 78 |
|
| 79 |
setting_reg #(.my_addr(BASE+7)) sr_samples_per_pkt |
| 80 |
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), |
| 81 |
.in(set_data),.out(samples_per_packet),.changed()); |
| 82 |
|
| 83 |
setting_reg #(.my_addr(BASE+8), .at_reset(1)) sr_numchan |
| 84 |
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), |
| 85 |
.in(set_data),.out(numchan),.changed()); |
| 86 |
|
| 87 |
// Output FIFO for packetized data |
| 88 |
localparam VITA_IDLE = 0; |
| 89 |
localparam VITA_HEADER = 1; |
| 90 |
localparam VITA_STREAMID = 2; |
| 91 |
localparam VITA_SECS = 3; |
| 92 |
localparam VITA_TICS = 4; |
| 93 |
localparam VITA_TICS2 = 5; |
| 94 |
localparam VITA_PAYLOAD = 6; |
| 95 |
localparam VITA_TRAILER = 7; |
| 96 |
localparam VITA_ERR_HEADER = 9; // All ERR at 4'b1000 or'ed with base |
| 97 |
localparam VITA_ERR_STREAMID = 10; |
| 98 |
localparam VITA_ERR_SECS = 11; |
| 99 |
localparam VITA_ERR_TICS = 12; |
| 100 |
localparam VITA_ERR_TICS2 = 13; |
| 101 |
localparam VITA_ERR_PAYLOAD = 14; |
| 102 |
localparam VITA_ERR_TRAILER = 15; // Extension context packets have no trailer |
| 103 |
|
| 104 |
always @(posedge clk) |
| 105 |
if(reset | clear_pkt_count) |
| 106 |
pkt_count <= 0; |
| 107 |
else if((vita_state == VITA_TRAILER) & pkt_fifo_rdy) |
| 108 |
pkt_count <= pkt_count + 1; |
| 109 |
|
| 110 |
wire has_streamid = vita_header[28]; |
| 111 |
wire has_trailer = vita_header[26]; |
| 112 |
reg trl_eob; |
| 113 |
|
| 114 |
always @* |
| 115 |
case(vita_state) |
| 116 |
// Data packets are IF Data packets with or w/o streamid, no classid, with trailer |
| 117 |
VITA_HEADER : pkt_fifo_line <= {2'b01,3'b000,vita_header[28],2'b01,vita_header[25:20],pkt_count,vita_pkt_len};
|
| 118 |
VITA_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid};
|
| 119 |
VITA_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
|
| 120 |
VITA_TICS : pkt_fifo_line <= {2'b00,32'd0};
|
| 121 |
VITA_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};
|
| 122 |
VITA_PAYLOAD : pkt_fifo_line <= {2'b00,data_fifo_o};
|
| 123 |
VITA_TRAILER : pkt_fifo_line <= {2'b10,vita_trailer[31:21],1'b1,vita_trailer[19:9],trl_eob,8'd0};
|
| 124 |
|
| 125 |
// Error packets are Extension Context packets, which have no trailer |
| 126 |
VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,4'b0101,4'b0000,vita_header[23:20],pkt_count,16'd6};
|
| 127 |
VITA_ERR_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid};
|
| 128 |
VITA_ERR_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
|
| 129 |
VITA_ERR_TICS : pkt_fifo_line <= {2'b00,32'd0};
|
| 130 |
VITA_ERR_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};
|
| 131 |
VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b11,28'd0,flags_fifo_o};
|
| 132 |
//VITA_ERR_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer};
|
| 133 |
|
| 134 |
default : pkt_fifo_line <= 34'h0_FFFF_FFFF; |
| 135 |
endcase // case (vita_state) |
| 136 |
|
| 137 |
always @(posedge clk) |
| 138 |
if(reset) |
| 139 |
begin |
| 140 |
vita_state <= VITA_IDLE; |
| 141 |
sample_ctr <= 0; |
| 142 |
sample_phase <= 0; |
| 143 |
end |
| 144 |
else |
| 145 |
if(vita_state==VITA_IDLE) |
| 146 |
begin |
| 147 |
sample_ctr <= 1; |
| 148 |
sample_phase <= 0; |
| 149 |
if(sample_fifo_src_rdy_i) |
| 150 |
if(|flags_fifo_o[3:1]) |
| 151 |
vita_state <= VITA_ERR_HEADER; |
| 152 |
else |
| 153 |
vita_state <= VITA_HEADER; |
| 154 |
end |
| 155 |
else if(pkt_fifo_rdy) |
| 156 |
case(vita_state) |
| 157 |
VITA_HEADER : |
| 158 |
if(has_streamid) |
| 159 |
vita_state <= VITA_STREAMID; |
| 160 |
else |
| 161 |
vita_state <= VITA_SECS; |
| 162 |
VITA_PAYLOAD : |
| 163 |
if(sample_fifo_src_rdy_i) |
| 164 |
begin |
| 165 |
if(sample_phase == (numchan-4'd1)) |
| 166 |
begin |
| 167 |
sample_phase <= 0; |
| 168 |
sample_ctr <= sample_ctr + 1; |
| 169 |
trl_eob <= flags_fifo_o[0]; |
| 170 |
if(sample_ctr == samples_per_packet) |
| 171 |
vita_state <= VITA_TRAILER; |
| 172 |
if(|flags_fifo_o) // end early if any flag is set |
| 173 |
vita_state <= VITA_TRAILER; |
| 174 |
end |
| 175 |
else |
| 176 |
sample_phase <= sample_phase + 1; |
| 177 |
end // if (sample_fifo_src_rdy_i) |
| 178 |
VITA_ERR_PAYLOAD : |
| 179 |
vita_state <= VITA_IDLE; |
| 180 |
VITA_TRAILER : |
| 181 |
vita_state <= VITA_IDLE; |
| 182 |
default : |
| 183 |
vita_state <= vita_state + 1; |
| 184 |
endcase // case (vita_state) |
| 185 |
|
| 186 |
reg req_write_pkt_fifo; |
| 187 |
always @* |
| 188 |
case(vita_state) |
| 189 |
VITA_IDLE : |
| 190 |
req_write_pkt_fifo <= 0; |
| 191 |
VITA_HEADER, VITA_STREAMID, VITA_SECS, VITA_TICS, VITA_TICS2, VITA_TRAILER : |
| 192 |
req_write_pkt_fifo <= 1; |
| 193 |
VITA_PAYLOAD : |
| 194 |
// Write if sample ready and no error flags |
| 195 |
req_write_pkt_fifo <= (sample_fifo_src_rdy_i & ~|flags_fifo_o[3:1]); |
| 196 |
VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_SECS, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD : |
| 197 |
req_write_pkt_fifo <= 1; |
| 198 |
default : |
| 199 |
req_write_pkt_fifo <= 0; |
| 200 |
endcase // case (vita_state) |
| 201 |
|
| 202 |
//wire req_write_pkt_fifo = (vita_state != VITA_IDLE) & (sample_fifo_src_rdy_i | (vita_state != VITA_PAYLOAD)); |
| 203 |
|
| 204 |
// Short FIFO to buffer between us and the FIFOs outside |
| 205 |
fifo_short #(.WIDTH(34)) rx_pkt_fifo |
| 206 |
(.clk(clk), .reset(reset), .clear(clear_int), |
| 207 |
.datain(pkt_fifo_line), .src_rdy_i(req_write_pkt_fifo), .dst_rdy_o(pkt_fifo_rdy), |
| 208 |
.dataout(data_o[33:0]), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i), |
| 209 |
.space(),.occupied(fifo_occupied[4:0]) ); |
| 210 |
assign fifo_occupied[15:5] = 0; |
| 211 |
assign data_o[35:34] = 2'b00; // Always write full lines |
| 212 |
assign sample_fifo_dst_rdy_o = pkt_fifo_rdy & |
| 213 |
( ((vita_state==VITA_PAYLOAD) & |
| 214 |
(sample_phase == (numchan-4'd1)) & |
| 215 |
~|flags_fifo_o[3:1]) | |
| 216 |
(vita_state==VITA_ERR_PAYLOAD)); |
| 217 |
|
| 218 |
assign debug_rx = vita_state; |
| 219 |
|
| 220 |
endmodule // rx_control |