diff options
author | Matt Ettus <matt@ettus.com> | 2012-01-29 18:23:23 -0800 |
---|---|---|
committer | Matt Ettus <matt@ettus.com> | 2012-01-29 23:09:00 -0800 |
commit | ac35b413a595617c1fa57766758c06ccfe3f320e (patch) | |
tree | 1d943efd65c5b1698299ec2d2594dfc33d0d1143 /usrp2/sdr_lib | |
parent | 724e4a9eba417bb053259f312060e5e3ebe4581d (diff) | |
download | uhd-ac35b413a595617c1fa57766758c06ccfe3f320e.tar.gz uhd-ac35b413a595617c1fa57766758c06ccfe3f320e.tar.bz2 uhd-ac35b413a595617c1fa57766758c06ccfe3f320e.zip |
dsp: 8 to 16 bit conversion for tx side. believed to be functional
Diffstat (limited to 'usrp2/sdr_lib')
-rw-r--r-- | usrp2/sdr_lib/dspengine_8to16.v | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/usrp2/sdr_lib/dspengine_8to16.v b/usrp2/sdr_lib/dspengine_8to16.v new file mode 100644 index 000000000..39cf440f6 --- /dev/null +++ b/usrp2/sdr_lib/dspengine_8to16.v @@ -0,0 +1,194 @@ + +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +module dspengine_8to16 + #(parameter BASE = 0, + parameter BUF_SIZE = 9) + (input clk, input reset, input clear, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + output access_we, + output access_stb, + input access_ok, + output access_done, + output access_skip_read, + output [BUF_SIZE-1:0] access_adr, + input [BUF_SIZE-1:0] access_len, + output [35:0] access_dat_o, + input [35:0] access_dat_i + ); + + wire convert; + + setting_reg #(.my_addr(BASE),.width(1)) sr_8to16 + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(convert),.changed()); + + reg [3:0] dsp_state; + localparam DSP_IDLE = 0; + localparam DSP_PARSE_HEADER = 1; + localparam DSP_READ = 2; + localparam DSP_WRITE_0 = 3; + localparam DSP_WRITE_1 = 4; + localparam DSP_READ_TRAILER = 5; + localparam DSP_WRITE_TRAILER = 6; + localparam DSP_WRITE_HEADER = 7; + localparam DSP_DONE = 8; + + // Parse VITA header + wire is_if_data = (access_dat_i[31:29] == 3'b000); + wire has_streamid = access_dat_i[28]; + wire has_classid = access_dat_i[27]; + wire has_trailer = access_dat_i[26]; + // 25:24 reserved, aka SOB/EOB + wire has_secs = |access_dat_i[23:22]; + wire has_tics = |access_dat_i[21:20]; + wire [3:0] hdr_length = 1 + has_streamid + has_classid + has_classid + has_secs + has_tics + has_tics; + reg [15:0] hdr_length_reg; + + reg odd; + + reg [BUF_SIZE-1:0] read_adr, write_adr; + reg has_trailer_reg; + + wire last = (read_adr + 1) == (access_len - has_trailer_reg); + + reg [31:0] new_header, new_trailer, trailer_mask; + reg [15:0] length; + reg wait_for_trailer; + reg [15:0] data_in_len, data_out_len; + + reg [7:0] i8_0, q8_0; + wire [7:0] i8_1 = access_dat_i[15:8]; + wire [7:0] q8_1 = access_dat_i[7:0]; + reg skip; + + + always @(posedge clk) + { i8_0, q8_0 } <= access_dat_i[31:16]; + + always @(posedge clk) + if(reset | clear) + dsp_state <= DSP_IDLE; + else + case(dsp_state) + DSP_IDLE : + begin + read_adr <= 0; + write_adr <= 0; + if(access_ok) + dsp_state <= DSP_PARSE_HEADER; + end + + DSP_PARSE_HEADER : + begin + // FIXME is data always valid here? + + has_trailer_reg <= has_trailer; + new_header[31:16] <= access_dat_i[31:16]; + new_header[15:0] <= access_len; + length <= access_len; + hdr_length_reg <= hdr_length; + if(~is_if_data | ~convert | ~has_trailer) + // ~convert is valid (16 bit mode) but both ~trailer and ~is_if_data are both + // really error conditions on the TX side. We shouldn't ever see them in the TX chain + dsp_state <= DSP_WRITE_HEADER; + else + begin + read_adr <= access_len-1; // point to trailer + dsp_state <= DSP_READ_TRAILER; + wait_for_trailer <= 0; + data_in_len <= access_len - hdr_length - 1; + end + end + + DSP_READ_TRAILER : + begin + wait_for_trailer <= 1; + if(wait_for_trailer) + dsp_state <= DSP_WRITE_TRAILER; + new_trailer <= access_dat_i[31:0]; // Leave trailer unchanged + odd <= access_dat_i[20] & access_dat_i[8]; + data_out_len <= {data_in_len,1'b0} - (access_dat_i[20] & access_dat_i[8]); + write_adr <= hdr_length_reg + {data_in_len,1'b0} - (access_dat_i[20] & access_dat_i[8]); + end + + DSP_WRITE_TRAILER : + begin + dsp_state <= DSP_READ; + write_adr <= write_adr - 1; + read_adr <= read_adr - 1; + new_header[15:0] <= write_adr + 1; // length = addr of trailer + 1 + end + + DSP_READ : + begin + dsp_state <= DSP_WRITE_1; + read_adr <= read_adr - 1; + end + + DSP_WRITE_1 : + begin + write_adr <= write_adr - 1; + odd <= 0; + if(write_adr == hdr_length_reg) + dsp_state <= DSP_WRITE_HEADER; + else if(odd) + dsp_state <= DSP_READ; + else + dsp_state <= DSP_WRITE_0; + end + + DSP_WRITE_0 : + begin + write_adr <= write_adr - 1; + if(write_adr == hdr_length_reg) + dsp_state <= DSP_WRITE_HEADER; + else + dsp_state <= DSP_READ; + end + + DSP_WRITE_HEADER : + dsp_state <= DSP_DONE; + + DSP_DONE : + begin + read_adr <= 0; + write_adr <= 0; + dsp_state <= DSP_IDLE; + end + endcase // case (dsp_state) + + assign access_skip_read = 0; + assign access_done = (dsp_state == DSP_DONE); + + assign access_stb = 1; + + assign access_we = (dsp_state == DSP_WRITE_HEADER) | + (dsp_state == DSP_WRITE_TRAILER) | + (dsp_state == DSP_WRITE_0) | + (dsp_state == DSP_WRITE_1); + + assign access_dat_o = (dsp_state == DSP_WRITE_HEADER) ? { 4'h1, new_header } : + (dsp_state == DSP_WRITE_TRAILER) ? { 4'h2, new_trailer } : + (dsp_state == DSP_WRITE_0) ? { 4'h0, i8_0, 8'd0, q8_0, 8'd0 } : + (dsp_state == DSP_WRITE_1) ? { 4'h0, i8_1, 8'd0, q8_1, 8'd0 } : + 34'h0DEADBEEF; + + assign access_adr = access_we ? write_adr : read_adr; + +endmodule // dspengine_16to8 |