diff options
| author | Josh Blum <josh@joshknows.com> | 2012-02-17 16:55:59 -0800 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2012-02-17 16:55:59 -0800 | 
| commit | ace4489066d1621a09e70650a00d736f0b03ed8c (patch) | |
| tree | f02b34b70da9e9beb0f34dc5e64d48daa5aa4bf6 /fpga/usrp2/vrt | |
| parent | 8f8ac3397aaa85b64aaa8722efdc1c0c40e93052 (diff) | |
| parent | 2e37dd87234e5beddd6f76fcda714916f761f812 (diff) | |
| download | uhd-ace4489066d1621a09e70650a00d736f0b03ed8c.tar.gz uhd-ace4489066d1621a09e70650a00d736f0b03ed8c.tar.bz2 uhd-ace4489066d1621a09e70650a00d736f0b03ed8c.zip  | |
Merge branch 'fpga_next' into next
Diffstat (limited to 'fpga/usrp2/vrt')
| -rw-r--r-- | fpga/usrp2/vrt/Makefile.srcs | 2 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/gen_context_pkt.v | 18 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_rx_chain.v | 31 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_rx_engine_glue.v | 95 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_rx_framer.v | 38 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_tx_chain.v | 103 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_tx_control.v | 17 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_tx_deframer.v | 99 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_tx_engine_glue.v | 99 | 
9 files changed, 382 insertions, 120 deletions
diff --git a/fpga/usrp2/vrt/Makefile.srcs b/fpga/usrp2/vrt/Makefile.srcs index 166ed44ef..84ba5dc29 100644 --- a/fpga/usrp2/vrt/Makefile.srcs +++ b/fpga/usrp2/vrt/Makefile.srcs @@ -15,4 +15,6 @@ vita_tx_chain.v \  gen_context_pkt.v \  trigger_context_pkt.v \  vita_pkt_gen.v \ +vita_rx_engine_glue.v \ +vita_tx_engine_glue.v \  )) diff --git a/fpga/usrp2/vrt/gen_context_pkt.v b/fpga/usrp2/vrt/gen_context_pkt.v index bdfca8237..d6674e887 100644 --- a/fpga/usrp2/vrt/gen_context_pkt.v +++ b/fpga/usrp2/vrt/gen_context_pkt.v @@ -32,12 +32,11 @@ module gen_context_pkt     localparam CTXT_PROT_ENG = 1;     localparam CTXT_HEADER = 2;     localparam CTXT_STREAMID = 3; -   localparam CTXT_SECS = 4; -   localparam CTXT_TICS = 5; -   localparam CTXT_TICS2 = 6; -   localparam CTXT_MESSAGE = 7; -   localparam CTXT_FLOWCTRL = 8; -   localparam CTXT_DONE = 9; +   localparam CTXT_TICS = 4; +   localparam CTXT_TICS2 = 5; +   localparam CTXT_MESSAGE = 6; +   localparam CTXT_FLOWCTRL = 7; +   localparam CTXT_DONE = 8;     reg [33:0] 	 data_int;     wire 	 src_rdy_int, dst_rdy_int; @@ -88,11 +87,10 @@ module gen_context_pkt     always @*       case(ctxt_state) -       CTXT_PROT_ENG : data_int <= { 2'b01, 13'b0, DSP_NUMBER[0], 1'b1, 1'b1, 16'd28 }; // UDP port 1 or 3 -       CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100001101, seqno, 16'd7 }; +       CTXT_PROT_ENG : data_int <= { 2'b01, 13'b0, DSP_NUMBER[0], 1'b1, 1'b1, 16'd24 }; // UDP port 1 or 3 +       CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100000001, seqno, 16'd6 };         CTXT_STREAMID : data_int <= { 2'b00, streamid }; -       CTXT_SECS : data_int <= { 2'b00, err_time[63:32] }; -       CTXT_TICS : data_int <= { 2'b00, 32'd0 }; +       CTXT_TICS : data_int <= { 2'b00, err_time[63:32] };         CTXT_TICS2 : data_int <= { 2'b00, err_time[31:0] };         CTXT_MESSAGE : data_int <= { 2'b00, message };         CTXT_FLOWCTRL : data_int <= { 2'b10, seqnum }; diff --git a/fpga/usrp2/vrt/vita_rx_chain.v b/fpga/usrp2/vrt/vita_rx_chain.v index 8b41e5fa8..c57e6cc05 100644 --- a/fpga/usrp2/vrt/vita_rx_chain.v +++ b/fpga/usrp2/vrt/vita_rx_chain.v @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -20,21 +20,31 @@ module vita_rx_chain    #(parameter BASE=0,      parameter UNIT=0,      parameter FIFOSIZE=10, -    parameter PROT_ENG_FLAGS=1) -   (input clk, input reset, input clear, +    parameter PROT_ENG_FLAGS=1, +    parameter DSP_NUMBER=0) +   (input clk, input reset,      input set_stb, input [7:0] set_addr, input [31:0] set_data, -    input [63:0] vita_time, output overrun, -    input [31:0] sample, output run, input strobe, +    input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, +    input [63:0] vita_time, +    input [31:0] sample, input strobe,      output [35:0] rx_data_o, output rx_src_rdy_o, input rx_dst_rdy_i, +    output overrun, output run, output clear_o,      output [31:0] debug ); -        +     wire [100:0] sample_data;     wire 	sample_dst_rdy, sample_src_rdy;     wire [31:0] 	vrc_debug, vrf_debug;     wire [35:0] 	rx_data_int;     wire 	rx_src_rdy_int, rx_dst_rdy_int; -    + +   wire clear; +   assign clear_o = clear; + +   setting_reg #(.my_addr(BASE+3)) sr +     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), +      .in(set_data),.out(),.changed(clear)); +     vita_rx_control #(.BASE(BASE), .WIDTH(32)) vita_rx_control       (.clk(clk), .reset(reset), .clear(clear),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), @@ -65,9 +75,10 @@ module vita_rx_chain        .data_i(rx_data_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int),        .data_o(rx_data_int2), .src_rdy_o(rx_src_rdy_int2), .dst_rdy_i(rx_dst_rdy_int2)); -   dspengine_16to8 #(.BASE(BASE+9), .BUF_SIZE(FIFOSIZE)) dspengine_16to8 -     (.clk(clk),.reset(reset),.clear(clear), -      .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), +   vita_rx_engine_glue #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+3), .BUF_SIZE(FIFOSIZE)) dspengine_rx +     (.clock(clk),.reset(reset),.clear(clear), +      .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), +      .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user),        .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),         .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),         .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); diff --git a/fpga/usrp2/vrt/vita_rx_engine_glue.v b/fpga/usrp2/vrt/vita_rx_engine_glue.v new file mode 100644 index 000000000..56447a7aa --- /dev/null +++ b/fpga/usrp2/vrt/vita_rx_engine_glue.v @@ -0,0 +1,95 @@ +// +// Copyright 2012 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/>. +// + +//The following module is used to re-write receive packets to the host. +//This module provides a packet-based ram interface for manipulating packets. +//By default, this module uses the built-in 16 to 8 bit converter engine. + +module vita_rx_engine_glue +#( +    //the dsp unit number: 0, 1, 2... +    parameter DSPNO = 0, + +    //buffer size for ram interface engine +    parameter BUF_SIZE = 10, + +    //base address for built-in settings registers used in this module +    parameter MAIN_SETTINGS_BASE = 0 +) +( +    //control signals +    input clock, input reset, input clear, + +    //main settings bus for built-in modules +    input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, + +    //user settings bus, controlled through user setting regs API +    input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + +    //ram interface for engine +    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, + +    //debug output (optional) +    output [31:0] debug +); + +    generate +        if (DSPNO==0) begin +            `ifndef RX_ENG0_MODULE +            dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8 +             (.clk(clock),.reset(reset),.clear(clear), +              .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), +              .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +              .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +              .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); +            `else +            `RX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng0_custom +             (.clock(clock),.reset(reset),.clear(clear), +              .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), +              .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +              .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +              .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); +            `endif +        end +        else begin +            `ifndef RX_ENG1_MODULE +            dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8 +             (.clk(clock),.reset(reset),.clear(clear), +              .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), +              .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +              .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +              .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); +            `else +            `RX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng1_custom +             (.clock(clock),.reset(reset),.clear(clear), +              .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), +              .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +              .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +              .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); +            `endif +        end +    endgenerate + +endmodule //vita_rx_engine_glue diff --git a/fpga/usrp2/vrt/vita_rx_framer.v b/fpga/usrp2/vrt/vita_rx_framer.v index bd09315bc..514df1151 100644 --- a/fpga/usrp2/vrt/vita_rx_framer.v +++ b/fpga/usrp2/vrt/vita_rx_framer.v @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -93,18 +93,16 @@ module vita_rx_framer     localparam VITA_IDLE 	 = 0;     localparam VITA_HEADER 	 = 1;     localparam VITA_STREAMID 	 = 2; -   localparam VITA_SECS 	 = 3; -   localparam VITA_TICS 	 = 4; -   localparam VITA_TICS2 	 = 5; -   localparam VITA_PAYLOAD 	 = 6; -   localparam VITA_TRAILER 	 = 7; -   localparam VITA_ERR_HEADER 	 = 9;  // All ERR at 4'b1000 or'ed with base -   localparam VITA_ERR_STREAMID  = 10; -   localparam VITA_ERR_SECS 	 = 11; -   localparam VITA_ERR_TICS 	 = 12; -   localparam VITA_ERR_TICS2 	 = 13; -   localparam VITA_ERR_PAYLOAD 	 = 14; -   localparam VITA_ERR_TRAILER 	 = 15; // Extension context packets have no trailer +   localparam VITA_TICS 	 = 3; +   localparam VITA_TICS2 	 = 4; +   localparam VITA_PAYLOAD 	 = 5; +   localparam VITA_TRAILER 	 = 6; +   localparam VITA_ERR_HEADER 	 = 7;  // All ERR at 4'b1000 or'ed with base +   localparam VITA_ERR_STREAMID  = 8; +   localparam VITA_ERR_TICS 	 = 9; +   localparam VITA_ERR_TICS2 	 = 10; +   localparam VITA_ERR_PAYLOAD 	 = 11; +   localparam VITA_ERR_TRAILER 	 = 12; // Extension context packets have no trailer     always @(posedge clk)       if(reset | clear | clear_pkt_count) @@ -122,17 +120,15 @@ module vita_rx_framer         VITA_HEADER : pkt_fifo_line <= {2'b01,3'b000,vita_header[28],2'b01,vita_header[25:24],  				       vita_header[23:20],pkt_count[3:0],vita_pkt_len[15:0]};         VITA_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid}; -       VITA_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]}; -       VITA_TICS : pkt_fifo_line <= {2'b00,32'd0}; +       VITA_TICS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};         VITA_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};         VITA_PAYLOAD : pkt_fifo_line <= {2'b00,data_fifo_o};         VITA_TRAILER : pkt_fifo_line <= {2'b10,vita_trailer[31:21],1'b1,vita_trailer[19:9],trl_eob,8'd0};         // Error packets are Extension Context packets, which have no trailer -       VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,4'b0101,4'b0000,vita_header[23:20],pkt_count,16'd6}; +       VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,4'b0101,4'b0000,vita_header[23:20],pkt_count,16'd5};         VITA_ERR_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid}; -       VITA_ERR_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]}; -       VITA_ERR_TICS : pkt_fifo_line <= {2'b00,32'd0}; +       VITA_ERR_TICS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};         VITA_ERR_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};         VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b10,27'd0,flags_fifo_o};         //VITA_ERR_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer}; @@ -164,7 +160,7 @@ module vita_rx_framer  	     if(has_streamid)  	       vita_state <= VITA_STREAMID;  	     else -	       vita_state <= VITA_SECS; +	       vita_state <= VITA_TICS;  	   VITA_PAYLOAD :  	     if(sample_fifo_src_rdy_i)  	       begin @@ -194,12 +190,12 @@ module vita_rx_framer       case(vita_state)         VITA_IDLE :  	 req_write_pkt_fifo <= 0; -       VITA_HEADER, VITA_STREAMID, VITA_SECS, VITA_TICS, VITA_TICS2, VITA_TRAILER : +       VITA_HEADER, VITA_STREAMID, VITA_TICS, VITA_TICS2, VITA_TRAILER :  	 req_write_pkt_fifo <= 1;         VITA_PAYLOAD :  	 // Write if sample ready and no error flags       	 req_write_pkt_fifo <= (sample_fifo_src_rdy_i & ~|flags_fifo_o[4:1]); -       VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_SECS, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD : +       VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD :  	 req_write_pkt_fifo <= 1;         default :  	 req_write_pkt_fifo <= 0; diff --git a/fpga/usrp2/vrt/vita_tx_chain.v b/fpga/usrp2/vrt/vita_tx_chain.v index ac9f08fc8..82a43d57a 100644 --- a/fpga/usrp2/vrt/vita_tx_chain.v +++ b/fpga/usrp2/vrt/vita_tx_chain.v @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -17,8 +17,9 @@  module vita_tx_chain -  #(parameter BASE_CTRL=0, -    parameter BASE_DSP=0, +  #(parameter BASE=0, +    parameter FIFOSIZE=10, +    parameter POST_ENGINE_FIFOSIZE=10,      parameter REPORT_ERROR=0,      parameter DO_FLOW_CONTROL=0,      parameter PROT_ENG_FLAGS=0, @@ -26,11 +27,12 @@ module vita_tx_chain      parameter DSP_NUMBER=0)     (input clk, input reset,      input set_stb, input [7:0] set_addr, input [31:0] set_data, +    input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user,      input [63:0] vita_time,      input [35:0] tx_data_i, input tx_src_rdy_i, output tx_dst_rdy_o,      output [35:0] err_data_o, output err_src_rdy_o, input err_dst_rdy_i, -    output [23:0] tx_i, output [23:0] tx_q, -    output underrun, output run, +    output [31:0] sample, input strobe, +    output underrun, output run, output clear_o,      output [31:0] debug);     localparam MAXCHAN = 1; @@ -38,8 +40,6 @@ module vita_tx_chain     wire [FIFOWIDTH-1:0] tx1_data;     wire 		tx1_src_rdy, tx1_dst_rdy; -   wire 		clear_vita; -   wire [31:0] 		sample_tx;     wire [31:0] 		streamid, message;     wire 		trigger, sent;     wire [31:0] 		debug_vtc, debug_vtd, debug_tx_dsp; @@ -48,61 +48,104 @@ module vita_tx_chain     wire [31:0] 		error_code;     wire 		clear_seqnum;     wire [31:0] 		current_seqnum; -   wire 		strobe_tx; -    + +   wire clear, flush; +   assign clear_o = clear;     assign underrun = error;     assign message = error_code; -    -   setting_reg #(.my_addr(BASE_CTRL+1)) sr + +   setting_reg #(.my_addr(BASE+0), .width(1)) sr       (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out(),.changed(clear_vita)); +      .in(set_data),.out(flush),.changed(clear)); -   setting_reg #(.my_addr(BASE_CTRL+2), .at_reset(0)) sr_streamid +   setting_reg #(.my_addr(BASE+2), .at_reset(0)) sr_streamid       (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),        .in(set_data),.out(streamid),.changed(clear_seqnum)); -   vita_tx_deframer #(.BASE(BASE_CTRL),  +    //flush control - full rate vacuum of input until flush cleared +    wire tx_dst_rdy_int, tx_src_rdy_int; +    wire [35:0] tx_data_int; +    valve36 flusher_valve +    (.clk(clk), .reset(reset), .clear(clear & flush), .shutoff(flush), +     .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), +     .data_o(tx_data_int), .src_rdy_o(tx_src_rdy_int), .dst_rdy_i(tx_dst_rdy_int)); + +   wire [35:0] tx_data_int1; +   wire tx_src_rdy_int1, tx_dst_rdy_int1; + +    generate +    if (FIFOSIZE==0) begin +        assign tx_data_int1 = tx_data_int; +        assign tx_src_rdy_int1 = tx_src_rdy_int; +        assign tx_dst_rdy_int = tx_dst_rdy_int1; +    end +    else begin +       wire [FIFOSIZE-1:0] access_adr, access_len; +       wire 	       access_we, access_stb, access_ok, access_done, access_skip_read; +       wire [35:0] 	       dsp_to_buf, buf_to_dsp; +       wire [35:0] tx_data_int0; +       wire tx_src_rdy_int0, tx_dst_rdy_int0; + +       double_buffer #(.BUF_SIZE(FIFOSIZE)) db +         (.clk(clk),.reset(reset),.clear(clear), +          .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), +          .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), +          .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), + +          .data_i(tx_data_int), .src_rdy_i(tx_src_rdy_int), .dst_rdy_o(tx_dst_rdy_int), +          .data_o(tx_data_int0), .src_rdy_o(tx_src_rdy_int0), .dst_rdy_i(tx_dst_rdy_int0)); + +       vita_tx_engine_glue #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+1), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_tx +         (.clock(clk),.reset(reset),.clear(clear), +          .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data), +          .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user), +          .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done), +          .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len), +          .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); + +       fifo_cascade #(.WIDTH(36), .SIZE(POST_ENGINE_FIFOSIZE)) post_engine_buffering( +        .clk(clk), .reset(reset), .clear(clear), +        .datain(tx_data_int0), .src_rdy_i(tx_src_rdy_int0), .dst_rdy_o(tx_dst_rdy_int0), +        .dataout(tx_data_int1), .src_rdy_o(tx_src_rdy_int1), .dst_rdy_i(tx_dst_rdy_int1)); + +    end +    endgenerate + +   vita_tx_deframer #(.BASE(BASE),   		      .MAXCHAN(MAXCHAN),   		      .USE_TRANS_HEADER(USE_TRANS_HEADER))      vita_tx_deframer -     (.clk(clk), .reset(reset), .clear(clear_vita), .clear_seqnum(clear_seqnum), +     (.clk(clk), .reset(reset), .clear(clear), .clear_seqnum(clear_seqnum),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), +      .data_i(tx_data_int1), .src_rdy_i(tx_src_rdy_int1), .dst_rdy_o(tx_dst_rdy_int1),        .sample_fifo_o(tx1_data), .sample_fifo_src_rdy_o(tx1_src_rdy), .sample_fifo_dst_rdy_i(tx1_dst_rdy),        .current_seqnum(current_seqnum),        .debug(debug_vtd) ); -   vita_tx_control #(.BASE(BASE_CTRL), .WIDTH(32*MAXCHAN)) vita_tx_control -     (.clk(clk), .reset(reset), .clear(clear_vita), +   vita_tx_control #(.BASE(BASE), .WIDTH(32*MAXCHAN)) vita_tx_control +     (.clk(clk), .reset(reset), .clear(clear),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),        .vita_time(vita_time), .error(error), .ack(ack), .error_code(error_code),        .sample_fifo_i(tx1_data), .sample_fifo_src_rdy_i(tx1_src_rdy), .sample_fifo_dst_rdy_o(tx1_dst_rdy), -      .sample(sample_tx), .run(run), .strobe(strobe_tx), .packet_consumed(packet_consumed), +      .sample(sample), .run(run), .strobe(strobe), .packet_consumed(packet_consumed),        .debug(debug_vtc) ); -    -   dsp_core_tx #(.BASE(BASE_DSP)) dsp_core_tx -     (.clk(clk),.rst(reset), -      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .sample(sample_tx), .run(run), .strobe(strobe_tx), -      .tx_i(tx_i),.tx_q(tx_q), -      .debug(debug_tx_dsp) );     wire [35:0] 		flow_data, err_data_int;     wire 		flow_src_rdy, flow_dst_rdy, err_src_rdy_int, err_dst_rdy_int;     gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS),.DSP_NUMBER(DSP_NUMBER)) gen_flow_pkt -     (.clk(clk), .reset(reset), .clear(clear_vita), +     (.clk(clk), .reset(reset), .clear(clear),        .trigger(trigger & (DO_FLOW_CONTROL==1)), .sent(),         .streamid(streamid), .vita_time(vita_time), .message(32'd0),        .seqnum(current_seqnum),        .data_o(flow_data), .src_rdy_o(flow_src_rdy), .dst_rdy_i(flow_dst_rdy)); -   trigger_context_pkt #(.BASE(BASE_CTRL)) trigger_context_pkt -     (.clk(clk), .reset(reset), .clear(clear_vita), +   trigger_context_pkt #(.BASE(BASE)) trigger_context_pkt +     (.clk(clk), .reset(reset), .clear(clear),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),        .packet_consumed(packet_consumed), .trigger(trigger));     gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS),.DSP_NUMBER(DSP_NUMBER)) gen_tx_err_pkt -     (.clk(clk), .reset(reset), .clear(clear_vita), +     (.clk(clk), .reset(reset), .clear(clear),        .trigger((error|ack) & (REPORT_ERROR==1)), .sent(),         .streamid(streamid), .vita_time(vita_time), .message(message),        .seqnum(current_seqnum), diff --git a/fpga/usrp2/vrt/vita_tx_control.v b/fpga/usrp2/vrt/vita_tx_control.v index 5df89bdbe..c3ce2b96a 100644 --- a/fpga/usrp2/vrt/vita_tx_control.v +++ b/fpga/usrp2/vrt/vita_tx_control.v @@ -50,11 +50,9 @@ module vita_tx_control     wire        now, early, late, too_early; -   // FIXME ignore too_early for now for timing reasons -   assign too_early = 0;     time_compare        time_compare (.time_now(vita_time), .trigger_time(send_time),  -		   .now(now), .early(early), .late(late), .too_early()); +		   .now(now), .early(early), .late(late), .too_early(too_early));     reg 	       late_qual, late_del; @@ -187,8 +185,17 @@ module vita_tx_control     assign sample_fifo_dst_rdy_o = (ibs_state == IBS_ERROR) | (strobe & (ibs_state == IBS_RUN));  // FIXME also cleanout -   assign sample = (ibs_state == IBS_RUN) ? sample_fifo_i[5+64+16+WIDTH-1:5+64+16] : {WIDTH{1'b0}}; -   //assign run = (ibs_state == IBS_RUN) | (ibs_state == IBS_CONT_BURST); +   //register the output sample +   reg [31:0] sample_held; +   assign sample = sample_held; +   always @(posedge clk) +     if(reset | clear) +        sample_held <= 0; +     else if (~run) +       sample_held <= 0; +     else if (strobe) +       sample_held <= sample_fifo_i[5+64+16+WIDTH-1:5+64+16]; +     assign error = send_error;     assign ack = send_ack; diff --git a/fpga/usrp2/vrt/vita_tx_deframer.v b/fpga/usrp2/vrt/vita_tx_deframer.v index 06ca27767..6919da11a 100644 --- a/fpga/usrp2/vrt/vita_tx_deframer.v +++ b/fpga/usrp2/vrt/vita_tx_deframer.v @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -85,7 +85,6 @@ module vita_tx_deframer     localparam VITA_TICS 	 = 6;     localparam VITA_TICS2 	 = 7;     localparam VITA_PAYLOAD 	 = 8; -   localparam VITA_STORE         = 9;     localparam VITA_TRAILER 	 = 10;     localparam VITA_DUMP          = 11; @@ -118,21 +117,7 @@ module vita_tx_deframer  	    <= 0;  	  seqnum_err <= 0;         end -     else  -       if((vita_state == VITA_STORE) & fifo_space) -	 if(vita_eof)   -	   if(eof) -	     vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; -	   else if(has_trailer_reg) -	     vita_state <= VITA_TRAILER; -	   else -	     vita_state <= VITA_DUMP; -   	 else -	   begin -	      vita_state <= VITA_PAYLOAD; -	      pkt_len <= pkt_len - 1; -	   end -       else if(src_rdy_i) +     else if(src_rdy_i & dst_rdy_o) begin //valid read  	 case(vita_state)  	   VITA_TRANS_HEADER :  	     begin @@ -184,14 +169,33 @@ module vita_tx_deframer  	     vita_state <= VITA_TICS2;  	   VITA_TICS2 :  	     vita_state <= VITA_PAYLOAD; -	   VITA_PAYLOAD : -	     if(line_done) -	       begin -		  vector_phase <= 0; -		  vita_state <= VITA_STORE; -	       end -	     else -	       vector_phase <= vector_phase + 1; + +        VITA_PAYLOAD : begin + +            //step through each element until line done, then reset +            vector_phase <= (line_done)? 0: vector_phase + 1; + +            //decrement the packet count after each line +            pkt_len <= (line_done)? pkt_len - 1 : pkt_len; + +            //end of frame reached, determine next state +            //otherwise, keep processing through the payload +            if (line_done && vita_eof) begin + +                if (eof) begin +                    vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; +                end +                else if (has_trailer_reg) begin +                    vita_state <= VITA_TRAILER; +                end +                else begin +                    vita_state <= VITA_DUMP; +                end + +            end //line_done && vita_eof + +        end //end VITA_PAYLOAD +  	   VITA_TRAILER :  	     if(eof)  	       vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; @@ -200,46 +204,53 @@ module vita_tx_deframer  	   VITA_DUMP :  	     if(eof)  	       vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; -	   VITA_STORE : -	     ;  	   default :  	     vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;  	 endcase // case (vita_state) -   assign line_done = (vector_phase == numchan); +     end //valid read + +   assign line_done = (MAXCHAN == 1)? 1 : (vector_phase == numchan);     wire [FIFOWIDTH-1:0] fifo_i;     reg [63:0] 		      send_time; -   reg [31:0] 		      sample_a, sample_b, sample_c, sample_d;     always @(posedge clk)       case(vita_state) -       VITA_SECS : +       VITA_TICS :  	 send_time[63:32] <= data_i[31:0];         VITA_TICS2 :  	 send_time[31:0] <= data_i[31:0];       endcase // case (vita_state) -    + +   //sample registers for de-framing a vector input +   reg [31:0] sample_reg [1:0];     always @(posedge clk) -     if(vita_state == VITA_PAYLOAD) -       case(vector_phase) -	 0: sample_a <= data_i[31:0]; -	 1: sample_b <= data_i[31:0]; -	 2: sample_c <= data_i[31:0]; -	 3: sample_d <= data_i[31:0]; -       endcase // case (vector_phase) -    -   wire 		      store = (vita_state == VITA_STORE); +     if(src_rdy_i && dst_rdy_o) +        sample_reg[vector_phase] <= data_i[31:0]; + +   wire store = (vita_state == VITA_PAYLOAD)? (src_rdy_i && line_done) : 0; +   assign dst_rdy_o = (vita_state == VITA_PAYLOAD)? fifo_space : 1; +     fifo_short #(.WIDTH(FIFOWIDTH)) short_tx_q       (.clk(clk), .reset(reset), .clear(clear),        .datain(fifo_i), .src_rdy_i(store), .dst_rdy_o(fifo_space),        .dataout(sample_fifo_o), .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i) ); -   // sob, eob, has_secs (send_at) ignored on all lines except first -   assign fifo_i = {sample_d,sample_c,sample_b,sample_a,seqnum_err,has_secs_reg,is_sob_reg,is_eob_reg,eop, -		    12'd0,seqnum_reg[3:0],send_time}; +    //assign registered/live data to the samples vector +    //the numchan'th sample vector is muxed to live data +    wire [(32*MAXCHAN)-1:0] samples; +    generate +    genvar i; +    for (i=0; i < MAXCHAN; i = i +1) begin : assign_samples +        wire live_data = (i == (MAXCHAN-1))? 1 : numchan == i; +        assign samples[32*i + 31:32*i] = (live_data)? data_i[31:0] : sample_reg[i]; +    end +    endgenerate -   assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ; +   // sob, eob, has_tics (send_at) ignored on all lines except first +   assign fifo_i = {samples,seqnum_err,has_tics_reg,is_sob_reg,is_eob_reg,eop, +		    12'd0,seqnum_reg[3:0],send_time};     assign debug = { { 8'b0 },  		    { 8'b0 }, diff --git a/fpga/usrp2/vrt/vita_tx_engine_glue.v b/fpga/usrp2/vrt/vita_tx_engine_glue.v new file mode 100644 index 000000000..db0d55dee --- /dev/null +++ b/fpga/usrp2/vrt/vita_tx_engine_glue.v @@ -0,0 +1,99 @@ +// +// Copyright 2012 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/>. +// + +//The following module is used to re-write transmit packets from the host. +//This module provides a packet-based ram interface for manipulating packets. +//By default, this module uses the built-in 8 to 16 bit converter engine. + +module vita_tx_engine_glue +#( +    //the dsp unit number: 0, 1, 2... +    parameter DSPNO = 0, + +    //buffer size for ram interface engine +    parameter BUF_SIZE = 10, + +    //base address for built-in settings registers used in this module +    parameter MAIN_SETTINGS_BASE = 0, + +    //the number of 32bit lines between start of buffer and vita header +    //the metadata before the header should be preserved by the engine +    parameter HEADER_OFFSET = 0 +) +( +    //control signals +    input clock, input reset, input clear, + +    //main settings bus for built-in modules +    input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main, + +    //user settings bus, controlled through user setting regs API +    input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user, + +    //ram interface for engine +    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, + +    //debug output (optional) +    output [31:0] debug +); + +    generate +        if (DSPNO==0) begin +            `ifndef TX_ENG0_MODULE +            dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16 +             (.clk(clock),.reset(reset),.clear(clear), +              .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), +              .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +              .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +              .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); +            `else +            `TX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng0_custom +             (.clock(clock),.reset(reset),.clear(clear), +              .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), +              .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +              .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +              .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); +            `endif +        end +        else begin +            `ifndef TX_ENG1_MODULE +            dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16 +             (.clk(clock),.reset(reset),.clear(clear), +              .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main), +              .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +              .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +              .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); +            `else +            `TX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng1_custom +             (.clock(clock),.reset(reset),.clear(clear), +              .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user), +              .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +              .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +              .access_dat_i(access_dat_i), .access_dat_o(access_dat_o)); +            `endif +        end +    endgenerate + +endmodule //vita_tx_engine_glue  | 
