summaryrefslogtreecommitdiffstats
path: root/usrp2/sdr_lib
diff options
context:
space:
mode:
authorMatt Ettus <matt@ettus.com>2012-01-29 18:23:23 -0800
committerMatt Ettus <matt@ettus.com>2012-01-29 23:09:00 -0800
commitac35b413a595617c1fa57766758c06ccfe3f320e (patch)
tree1d943efd65c5b1698299ec2d2594dfc33d0d1143 /usrp2/sdr_lib
parent724e4a9eba417bb053259f312060e5e3ebe4581d (diff)
downloaduhd-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.v194
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