diff options
| author | Josh Blum <josh@joshknows.com> | 2011-08-31 18:29:34 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2011-08-31 18:29:34 -0700 | 
| commit | d6d017aa58fd858a752ac43a6a6c24704758e444 (patch) | |
| tree | 6f4b3388754d00d149a14c97f4ce6764e5d9a60c /fpga/usrp2 | |
| parent | 208885b6dc8a01a1d7095cff5b36c8451601259c (diff) | |
| parent | 4f04b93d23015a56b2a2d4e87541b24de36c9018 (diff) | |
| download | uhd-d6d017aa58fd858a752ac43a6a6c24704758e444.tar.gz uhd-d6d017aa58fd858a752ac43a6a6c24704758e444.tar.bz2 uhd-d6d017aa58fd858a752ac43a6a6c24704758e444.zip | |
Merge branch 'fpga_master' into next
Diffstat (limited to 'fpga/usrp2')
26 files changed, 552 insertions, 990 deletions
| diff --git a/fpga/usrp2/control_lib/atr_controller16.v b/fpga/usrp2/control_lib/atr_controller16.v index 727f8c630..578da4a5c 100644 --- a/fpga/usrp2/control_lib/atr_controller16.v +++ b/fpga/usrp2/control_lib/atr_controller16.v @@ -22,7 +22,7 @@  module atr_controller16    (input clk_i, input rst_i, -   input [5:0] adr_i, input [1:0] sel_i, input [15:0] dat_i, output reg [15:0] dat_o, +   input [5:0] adr_i, input [1:0] sel_i, input [15:0] dat_i, output [15:0] dat_o,     input we_i, input stb_i, input cyc_i, output reg ack_o,     input run_rx, input run_tx,     output [31:0] ctrl_lines); @@ -50,8 +50,7 @@ module atr_controller16     // Removing readback allows ram to be synthesized as LUTs instead of regs     //always @(posedge clk_i)     //  dat_o <= adr_i[1] ? atr_ram[adr_i[5:2]][31:16] : atr_ram[adr_i[5:2]][15:0]; -   always -     dat_o <= 16'd0; +   assign dat_o = 16'd0;     always @(posedge clk_i)       ack_o <= stb_i & cyc_i & ~ack_o; diff --git a/fpga/usrp2/gpmc/Makefile.srcs b/fpga/usrp2/gpmc/Makefile.srcs index bff6ae3e0..4c6a1b4a2 100644 --- a/fpga/usrp2/gpmc/Makefile.srcs +++ b/fpga/usrp2/gpmc/Makefile.srcs @@ -1,20 +1,14 @@  # -# Copyright 2010 Ettus Research LLC +# Copyright 2010-2011 Ettus Research LLC  #  ################################################## -# SERDES Sources +# GPMC Sources  ##################################################  GPMC_SRCS = $(abspath $(addprefix $(BASE_DIR)/../gpmc/, \ -dbsm.v \ -edge_sync.v \ -fifo_to_gpmc_async.v \ -fifo_to_gpmc_sync.v \ -fifo_watcher.v \ -gpmc_async.v \ -gpmc_sync.v \ -gpmc_to_fifo_async.v \ -gpmc_to_fifo_sync.v \ +cross_clock_reader.v \ +fifo_to_gpmc.v \ +gpmc.v \ +gpmc_to_fifo.v \  gpmc_wb.v \ -ram_to_fifo.v \  )) diff --git a/fpga/usrp2/gpmc/burst_data_write.txt b/fpga/usrp2/gpmc/burst_data_write.txt deleted file mode 100644 index 3b5dfc785..000000000 --- a/fpga/usrp2/gpmc/burst_data_write.txt +++ /dev/null @@ -1,16 +0,0 @@ -# OMAP burst writes to FPGA - -CLK=0,nWE=1,nCS=1,nOE=1,DATA=Z. -CLK=1. -CLK=0,nWE=0,nCS=0,DATA=WR_DATA1. -CLK=1. -CLK=0,nWE=0,nCS=0,DATA=WR_DATA2. -CLK=1. -CLK=0,nWE=0,nCS=0,DATA=WR_DATA3. -CLK=1. -CLK=0,nWE=0,nCS=0,DATA=WR_DATA4. -CLK=1. -CLK=0,nWE=1,nCS=1,DATA=Z. -CLK=1. - - diff --git a/fpga/usrp2/gpmc/edge_sync.v b/fpga/usrp2/gpmc/cross_clock_reader.v index 74f1a2f1c..a30e0385f 100644 --- a/fpga/usrp2/gpmc/edge_sync.v +++ b/fpga/usrp2/gpmc/cross_clock_reader.v @@ -15,25 +15,28 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // +module cross_clock_reader +    #( +        parameter WIDTH = 1, +        parameter DEFAULT = 0 +    ) +    ( +        input clk, input rst, +        input [WIDTH-1:0] in, +        output reg [WIDTH-1:0] out +    ); +    reg [WIDTH-1:0] shadow; -module edge_sync -  #(parameter POSEDGE = 1) -   (input clk, -    input rst, -    input sig, -    output trig); -    -   reg [1:0] delay; -    -   always @(posedge clk) -     if(rst) -       delay <= 2'b00; -     else -       delay <= {delay[0],sig}; -    -   assign trig = POSEDGE ? (delay==2'b01) : (delay==2'b10); -    -endmodule // edge_sync - +    always @(posedge clk) begin +        if (rst) begin +            out <= DEFAULT; +            shadow <= DEFAULT; +        end +        else if (shadow == in) begin +            out <= shadow; +        end +        shadow <= in; +    end +endmodule //cross_clock_reader diff --git a/fpga/usrp2/gpmc/dbsm.v b/fpga/usrp2/gpmc/dbsm.v deleted file mode 100644 index 1ee250738..000000000 --- a/fpga/usrp2/gpmc/dbsm.v +++ /dev/null @@ -1,97 +0,0 @@ -// -// 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 bsm -  (input clk, input reset, input clear, -   input write_done, -   input read_done, -   output readable, -   output writeable); - -   reg 	  state; -   localparam ST_WRITEABLE = 0; -   localparam ST_READABLE = 1; -    -   always @(posedge clk) -     if(reset | clear) -       state <= ST_WRITEABLE; -     else -       case(state) -	 ST_WRITEABLE : -	   if(write_done) -	     state <= ST_READABLE; -	 ST_READABLE : -	   if(read_done) -	     state <= ST_WRITEABLE; -       endcase // case (state) - -   assign readable = (state == ST_READABLE); -   assign writeable = (state == ST_WRITEABLE); -    -endmodule // bsm - -module dbsm -  (input clk, input reset, input clear, -   output reg read_sel, output read_ready, input read_done, -   output reg write_sel, output write_ready, input write_done); - -   localparam NUM_BUFS = 2; - -   wire       [NUM_BUFS-1:0] readable, writeable, read_done_buf, write_done_buf; -    -   // Two of these buffer state machines -   genvar     i; -   generate -      for(i=0;i<NUM_BUFS;i=i+1) -	begin : BSMS -	   bsm bsm(.clk(clk), .reset(reset), .clear(clear), -		   .write_done((write_sel == i) & write_done), -		   .read_done((read_sel == i) & read_done), -		   .readable(readable[i]), .writeable(writeable[i])); -	end -   endgenerate -    -   reg 	 full; -    -   always @(posedge clk) -     if(reset | clear) -       begin -	  write_sel <= 0; -	  full <= 0; -       end -     else -       if(write_done & writeable[write_sel]) -	 if(write_sel ==(NUM_BUFS-1)) -	   write_sel <= 0; -	 else -	   write_sel <= write_sel + 1; -    -   always @(posedge clk) -     if(reset | clear) -       read_sel <= 0; -     else -       if(read_done & readable[read_sel]) -	 if(read_sel==(NUM_BUFS-1)) -	   read_sel <= 0; -	 else -	   read_sel <= read_sel + 1; -           -   assign write_ready = writeable[write_sel]; -   assign read_ready = readable[read_sel]; - -endmodule // dbsm diff --git a/fpga/usrp2/gpmc/fifo_to_gpmc.v b/fpga/usrp2/gpmc/fifo_to_gpmc.v new file mode 100644 index 000000000..42c71d2d6 --- /dev/null +++ b/fpga/usrp2/gpmc/fifo_to_gpmc.v @@ -0,0 +1,159 @@ +// +// 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/>. +// + +//////////////////////////////////////////////////////////////////////// +// FIFO to GPMC +// +// Reads frames from FIFO interface and writes them into BRAM pages. +// The GPMC is asynchronously alerted when a BRAM page has been filled. +// +// EM_CLK: +// A GPMC read transaction consists of two EM_CLK cycles (idle low). +// +// EM_OE: +// Output enable is actually the combination of ~NOE & ~NCS. +// The output enable is only active for the second rising edge, +// to ensure one edge per transaction to transition on. +// +// EM_D: +// The BRAM performs a read on the first rising edge into EM_D. +// Then, data will then be read on the next rising edge by GPMC. +// +// EM_A: +// On the first rising edge of EM_CLK, the address is held. +// On the second rising edge, the address is set for the next transaction. +//////////////////////////////////////////////////////////////////////// + +module fifo_to_gpmc +  #(parameter PTR_WIDTH = 2, parameter ADDR_WIDTH = 10) +  (input clk, input reset, input clear, input arst, +   input [17:0] data_i, input src_rdy_i, output dst_rdy_o, +   output [15:0] EM_D, input [ADDR_WIDTH:1] EM_A, input EM_CLK, input EM_OE, +   output reg data_available); + +    //states for the GPMC side of things +    wire [17:0] data_o; +    reg gpmc_state; +    reg [ADDR_WIDTH:1] addr; +    reg [PTR_WIDTH:0] gpmc_ptr, next_gpmc_ptr; +    localparam GPMC_STATE_START = 0; +    localparam GPMC_STATE_EMPTY = 1; + +    //states for the FIFO side of things +    reg fifo_state; +    reg [ADDR_WIDTH-1:0] counter; +    reg [PTR_WIDTH:0] fifo_ptr; +    localparam FIFO_STATE_CLAIM = 0; +    localparam FIFO_STATE_FILL = 1; + +    //------------------------------------------------------------------ +    // State machine to control the data from GPMC to BRAM +    //------------------------------------------------------------------ +    always @(posedge EM_CLK or posedge arst) begin +        if (arst) begin +            gpmc_state <= GPMC_STATE_START; +            gpmc_ptr <= 0; +            next_gpmc_ptr <= 0; +            addr <= 0; +        end +        else if (EM_OE) begin +            addr <= EM_A + 1; +            case(gpmc_state) + +            GPMC_STATE_START: begin +                if (EM_A == 0) begin +                    gpmc_state <= GPMC_STATE_EMPTY; +                    next_gpmc_ptr <= gpmc_ptr + 1; +                end +            end + +            GPMC_STATE_EMPTY: begin +                if (EM_A == 10'h3ff) begin +                    gpmc_state <= GPMC_STATE_START; +                    gpmc_ptr <= next_gpmc_ptr; +                end +            end + +            endcase //gpmc_state +        end //EM_WE +    end //always + +    //------------------------------------------------------------------ +    // High when the gpmc pointer has not caught up to the fifo pointer. +    //------------------------------------------------------------------ +    wire [PTR_WIDTH:0] safe_gpmc_ptr; +    cross_clock_reader #(.WIDTH(PTR_WIDTH+1)) read_gpmc_ptr +        (.clk(clk), .rst(reset | clear), .in(gpmc_ptr), .out(safe_gpmc_ptr)); + +    wire bram_available_to_fill = (fifo_ptr ^ (1 << PTR_WIDTH)) != safe_gpmc_ptr; + +    //------------------------------------------------------------------ +    // Glich free generation of data available signal: +    // Data is available when the pointers dont match. +    //------------------------------------------------------------------ +    wire [PTR_WIDTH:0] safe_next_gpmc_ptr; +    cross_clock_reader #(.WIDTH(PTR_WIDTH+1)) read_next_gpmc_ptr +        (.clk(clk), .rst(reset | clear), .in(next_gpmc_ptr), .out(safe_next_gpmc_ptr)); + +    always @(posedge clk) +        if (reset | clear) data_available <= 0; +        else               data_available <= safe_next_gpmc_ptr != fifo_ptr; + +    //------------------------------------------------------------------ +    // State machine to control the data from BRAM to FIFO +    //------------------------------------------------------------------ +    always @(posedge clk) begin +        if (reset | clear) begin +            fifo_state <= FIFO_STATE_CLAIM; +            fifo_ptr <= 0; +            counter <= 0; +        end +        else begin +            case(fifo_state) + +            FIFO_STATE_CLAIM: begin +                if (bram_available_to_fill) fifo_state <= FIFO_STATE_FILL; +                counter <= 0; +            end + +            FIFO_STATE_FILL: begin +                if (src_rdy_i && dst_rdy_o && data_i[17]) begin +                    fifo_state <= FIFO_STATE_CLAIM; +                    fifo_ptr <= fifo_ptr + 1; +                end +                if (src_rdy_i && dst_rdy_o) begin +                    counter <= counter + 1; +                end +            end + +            endcase //fifo_state +        end +    end //always + +    assign dst_rdy_o = fifo_state == FIFO_STATE_FILL; + +    //assign data from bram output +    assign EM_D = data_o[15:0]; + +    //instantiate dual ported bram for async read + write +    ram_2port #(.DWIDTH(18),.AWIDTH(PTR_WIDTH + ADDR_WIDTH)) async_fifo_bram +     (.clka(clk),.ena(1'b1),.wea(src_rdy_i && dst_rdy_o), +      .addra({fifo_ptr[PTR_WIDTH-1:0], counter}),.dia(data_i),.doa(), +      .clkb(EM_CLK),.enb(1'b1),.web(1'b0), +      .addrb({gpmc_ptr[PTR_WIDTH-1:0], addr}),.dib(18'h3ffff),.dob(data_o)); + +endmodule // fifo_to_gpmc diff --git a/fpga/usrp2/gpmc/fifo_to_gpmc_async.v b/fpga/usrp2/gpmc/fifo_to_gpmc_async.v deleted file mode 100644 index bb4c58ec4..000000000 --- a/fpga/usrp2/gpmc/fifo_to_gpmc_async.v +++ /dev/null @@ -1,49 +0,0 @@ -// -// 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 fifo_to_gpmc_async -  (input clk, input reset, input clear, -   input [17:0] data_i, input src_rdy_i, output dst_rdy_o, -   output [15:0] EM_D, input EM_NCS, input EM_NOE, -   input [15:0] frame_len); - -   // Synchronize the async control signals -   reg [2:0] 	cs_del, oe_del; -   reg [15:0] 	counter; -    -   always @(posedge clk) -     if(reset) -       begin -	  cs_del <= 3'b11; -	  oe_del <= 3'b11; -       end -     else -       begin -	  cs_del <= { cs_del[1:0], EM_NCS }; -	  oe_del <= { oe_del[1:0], EM_NOE }; -       end - -   wire do_read = ( (~cs_del[1] | ~cs_del[2]) & (oe_del[1:0] == 2'b01));  // change output on trailing edge -   wire first_read = (counter == 0); -   wire last_read = ((counter+1) == frame_len); - -   assign EM_D = data_i[15:0]; - -   assign dst_rdy_o = do_read; - -endmodule // fifo_to_gpmc_async diff --git a/fpga/usrp2/gpmc/fifo_to_gpmc_sync.v b/fpga/usrp2/gpmc/fifo_to_gpmc_sync.v deleted file mode 100644 index 9da9caf86..000000000 --- a/fpga/usrp2/gpmc/fifo_to_gpmc_sync.v +++ /dev/null @@ -1,43 +0,0 @@ -// -// 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/>. -// - - -// Assumes a GPMC cycle with GPMC clock, as in the timing diagrams -//   If a packet bigger or smaller than we are told is sent, behavior is undefined. -//   If dst_rdy_i is low when we get data, behavior is undefined and we signal bus error. -//   If there is a bus error, we should be reset - -module fifo_to_gpmc_sync -  (input arst, -   input [17:0] data_i, input src_rdy_i, output dst_rdy_o, -   input EM_CLK, output [15:0] EM_D, input EM_NCS, input EM_NOE, -   output fifo_ready,  -   output reg bus_error); - -   assign EM_D = data_i[15:0]; -   wire       read_access = ~EM_NCS & ~EM_NOE; - -   assign dst_rdy_o = read_access; - -   always @(posedge EM_CLK or posedge arst) -     if(arst) -       bus_error <= 0; -     else if(dst_rdy_o & ~src_rdy_i) -       bus_error <= 1; -    - -endmodule // fifo_to_gpmc_sync diff --git a/fpga/usrp2/gpmc/fifo_watcher.v b/fpga/usrp2/gpmc/fifo_watcher.v deleted file mode 100644 index b139f5143..000000000 --- a/fpga/usrp2/gpmc/fifo_watcher.v +++ /dev/null @@ -1,73 +0,0 @@ -// -// 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 fifo_watcher -  (input clk, input reset, input clear, -   input src_rdy1, input dst_rdy1, input sof1, input eof1, -   input src_rdy2, input dst_rdy2, input sof2, input eof2, -   output reg have_packet, output [15:0] length, output reg bus_error, -   output [31:0] debug); - -   wire   write = src_rdy1 & dst_rdy1 & eof1; -   wire   read = src_rdy2 & dst_rdy2 & eof2; -   wire   have_packet_int; -   reg [15:0] counter; -   wire [4:0] pkt_count; -   assign debug = pkt_count; -    -   fifo_short #(.WIDTH(16)) frame_lengths -     (.clk(clk), .reset(reset), .clear(clear), -      .datain(counter), .src_rdy_i(write), .dst_rdy_o(), -      .dataout(length), .src_rdy_o(have_packet_int), .dst_rdy_i(read), -      .occupied(pkt_count), .space()); - -   always @(posedge clk) -     if(reset | clear) -       counter <= 1;   // Start at 1 -     else if(src_rdy1 & dst_rdy1) -       if(eof1) -	 counter <= 1; -       else -	 counter <= counter + 1; - -   always @(posedge clk) -     if(reset | clear) -       bus_error <= 0; -     else if(dst_rdy2 & ~src_rdy2) -       bus_error <= 1; -     else if(read & ~have_packet_int) -       bus_error <= 1; - -   reg 	      in_packet; -   always @(posedge clk) -     if(reset | clear) -       have_packet <= 0; -     else  -       have_packet <= (have_packet_int & ~in_packet) | (pkt_count>1) ; -    -   always @(posedge clk) -     if(reset | clear) -       in_packet <= 0; -     else if(src_rdy2 & dst_rdy2) -       if(eof2) -	 in_packet <= 0; -       else -	 in_packet <= 1; -    -endmodule // fifo_watcher diff --git a/fpga/usrp2/gpmc/gpmc.v b/fpga/usrp2/gpmc/gpmc.v new file mode 100644 index 000000000..a5d4db466 --- /dev/null +++ b/fpga/usrp2/gpmc/gpmc.v @@ -0,0 +1,159 @@ +// +// 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 gpmc +  #(parameter TXFIFOSIZE = 11,  +    parameter RXFIFOSIZE = 11, +    parameter ADDR_WIDTH = 10, +    parameter BUSDEBUG = 1) +   (// GPMC signals +    input arst, +    input EM_CLK, inout [15:0] EM_D, input [ADDR_WIDTH:1] EM_A, input [1:0] EM_NBE, +    input EM_WAIT0, input EM_NCS4, input EM_NCS6, input EM_NWE, input EM_NOE, +     +    // GPIOs for FIFO signalling +    output rx_have_data, output tx_have_space, +     +    // Wishbone signals +    input wb_clk, input wb_rst, +    output [ADDR_WIDTH:0] wb_adr_o, output [15:0] wb_dat_mosi, input [15:0] wb_dat_miso, +    output [1:0] wb_sel_o, output wb_cyc_o, output wb_stb_o, output wb_we_o, input wb_ack_i, +     +    // FIFO interface +    input fifo_clk, input fifo_rst, input clear_tx, input clear_rx, +    output [35:0] tx_data_o, output tx_src_rdy_o, input tx_dst_rdy_i, +    input [35:0] rx_data_i, input rx_src_rdy_i, output rx_dst_rdy_o, + +    output tx_underrun, output rx_overrun, +    input [7:0] test_rate, input [3:0] test_ctrl, +    output [31:0] debug +    ); + +   wire 	  EM_output_enable = (~EM_NOE & (~EM_NCS4 | ~EM_NCS6)); +   wire [15:0] 	  EM_D_fifo; +   wire [15:0] 	  EM_D_wb; + +   assign EM_D = ~EM_output_enable ? 16'bz : ~EM_NCS4 ? EM_D_fifo : EM_D_wb; + +   // CS4 is RAM_2PORT for DATA PATH (high-speed data) +   //    Writes go into one RAM, reads come from the other +   // CS6 is for CONTROL PATH (wishbone) + +   // //////////////////////////////////////////// +   // TX Data Path + +   wire [17:0] 	  tx18_data; +   wire 	  tx18_src_rdy, tx18_dst_rdy; +   wire [35:0] 	  tx_data, txb_data; +   wire 	  tx_src_rdy, tx_dst_rdy; +   wire 	  txb_src_rdy, txb_dst_rdy; + +   gpmc_to_fifo #(.ADDR_WIDTH(ADDR_WIDTH)) gpmc_to_fifo +     (.EM_D(EM_D), .EM_A(EM_A), .EM_CLK(EM_CLK), .EM_WE(~EM_NCS4 & ~EM_NWE), +      .clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), .arst(fifo_rst | clear_tx | arst), +      .data_o(tx18_data), .src_rdy_o(tx18_src_rdy), .dst_rdy_i(tx18_dst_rdy), +      .have_space(tx_have_space)); + +   fifo19_to_fifo36 #(.LE(1)) f19_to_f36   // Little endian because ARM is LE +     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), +      .f19_datain({1'b0,tx18_data}), .f19_src_rdy_i(tx18_src_rdy), .f19_dst_rdy_o(tx18_dst_rdy), +      .f36_dataout(txb_data), .f36_src_rdy_o(txb_src_rdy), .f36_dst_rdy_i(txb_dst_rdy)); + +   fifo_cascade #(.WIDTH(36), .SIZE(TXFIFOSIZE)) tx_buffering( +        .clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), +        .datain(txb_data), .src_rdy_i(txb_src_rdy), .dst_rdy_o(txb_dst_rdy), +        .dataout(tx_data), .src_rdy_o(tx_src_rdy), .dst_rdy_i(tx_dst_rdy) +   ); + +   // //////////////////////////////////////////// +   // RX Data Path +    +   wire [17:0] 	  rx18_data; +   wire 	  rx18_src_rdy, rx18_dst_rdy; +   wire [35:0] 	  rx_data, rxb_data; +   wire 	  rx_src_rdy, rx_dst_rdy; +   wire 	  rxb_src_rdy, rxb_dst_rdy; +   wire 	  dummy; + +   fifo_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_buffering( +        .clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), +        .datain(rx_data), .src_rdy_i(rx_src_rdy), .dst_rdy_o(rx_dst_rdy), +        .dataout(rxb_data), .src_rdy_o(rxb_src_rdy), .dst_rdy_i(rxb_dst_rdy) +   ); + +   fifo36_to_fifo19 #(.LE(1)) f36_to_f19   // Little endian because ARM is LE +     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), +      .f36_datain(rxb_data), .f36_src_rdy_i(rxb_src_rdy), .f36_dst_rdy_o(rxb_dst_rdy), +      .f19_dataout({dummy,rx18_data}), .f19_src_rdy_o(rx18_src_rdy), .f19_dst_rdy_i(rx18_dst_rdy) ); + +   fifo_to_gpmc #(.ADDR_WIDTH(ADDR_WIDTH)) fifo_to_gpmc +     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), .arst(fifo_rst | clear_rx | arst), +      .data_i(rx18_data), .src_rdy_i(rx18_src_rdy), .dst_rdy_o(rx18_dst_rdy), +      .EM_D(EM_D_fifo), .EM_A(EM_A), .EM_CLK(EM_CLK), .EM_OE(~EM_NCS4 & ~EM_NOE), +      .data_available(rx_have_data)); + +   // //////////////////////////////////////////// +   // Control path on CS6 +    +   gpmc_wb gpmc_wb +     (.EM_CLK(EM_CLK), .EM_D_in(EM_D), .EM_D_out(EM_D_wb), .EM_A(EM_A), .EM_NBE(EM_NBE), +      .EM_WE(~EM_NCS6 & ~EM_NWE), .EM_OE(~EM_NCS6 & ~EM_NOE), +      .wb_clk(wb_clk), .wb_rst(wb_rst), +      .wb_adr_o(wb_adr_o), .wb_dat_mosi(wb_dat_mosi), .wb_dat_miso(wb_dat_miso), +      .wb_sel_o(wb_sel_o), .wb_cyc_o(wb_cyc_o), .wb_stb_o(wb_stb_o), .wb_we_o(wb_we_o), +      .wb_ack_i(wb_ack_i) ); + +   // //////////////////////////////////////////// +   // Test support, traffic generator, loopback, etc. + +   // RX side muxes test data into the same stream +   wire [35:0] loopbackrx_data, testrx_data; +   wire [35:0] loopbacktx_data, testtx_data; +   wire        loopbackrx_src_rdy, loopbackrx_dst_rdy; +   wire        loopbacktx_src_rdy, loopbacktx_dst_rdy; +   wire        sel_testtx = test_ctrl[0]; + +   fifo36_mux rx_test_mux_lvl_2 +     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), +      .data0_i(loopbackrx_data), .src0_rdy_i(loopbackrx_src_rdy), .dst0_rdy_o(loopbackrx_dst_rdy), +      .data1_i(rx_data_i), .src1_rdy_i(rx_src_rdy_i), .dst1_rdy_o(rx_dst_rdy_o), +      .data_o(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy)); + +   fifo_short #(.WIDTH(36)) loopback_fifo +     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx | clear_rx), +      .datain(loopbacktx_data), .src_rdy_i(loopbacktx_src_rdy), .dst_rdy_o(loopbacktx_dst_rdy), +      .dataout(loopbackrx_data), .src_rdy_o(loopbackrx_src_rdy), .dst_rdy_i(loopbackrx_dst_rdy)); + +   // Crossbar used as a demux for switching TX stream to main DSP or to test logic +   crossbar36 tx_crossbar_lvl_1 +     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), +      .cross(sel_testtx), +      .data0_i(tx_data), .src0_rdy_i(tx_src_rdy), .dst0_rdy_o(tx_dst_rdy), +      .data1_i(tx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(),  // No 2nd input +      .data0_o(tx_data_o), .src0_rdy_o(tx_src_rdy_o), .dst0_rdy_i(tx_dst_rdy_i), +      .data1_o(loopbacktx_data), .src1_rdy_o(loopbacktx_src_rdy), .dst1_rdy_i(loopbacktx_dst_rdy) ); + +   assign debug = { +        EM_D, //16 +        EM_A, //10 +        EM_CLK, EM_NCS4, EM_NWE, EM_NOE, //4 +        EM_NCS6, wb_ack_i +   }; + +endmodule // gpmc diff --git a/fpga/usrp2/gpmc/gpmc_async.v b/fpga/usrp2/gpmc/gpmc_async.v deleted file mode 100644 index c0bec683a..000000000 --- a/fpga/usrp2/gpmc/gpmc_async.v +++ /dev/null @@ -1,245 +0,0 @@ -// -// 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 gpmc_async -  #(parameter TXFIFOSIZE = 11,  -    parameter RXFIFOSIZE = 11, -    parameter BUSDEBUG = 1) -   (// GPMC signals -    input arst, -    input EM_CLK, inout [15:0] EM_D, input [10:1] EM_A, input [1:0] EM_NBE, -    input EM_WAIT0, input EM_NCS4, input EM_NCS6, input EM_NWE, input EM_NOE, -     -    // GPIOs for FIFO signalling -    output rx_have_data, output tx_have_space, output reg bus_error, input bus_reset, -     -    // Wishbone signals -    input wb_clk, input wb_rst, -    output [10:0] wb_adr_o, output [15:0] wb_dat_mosi, input [15:0] wb_dat_miso, -    output [1:0] wb_sel_o, output wb_cyc_o, output wb_stb_o, output wb_we_o, input wb_ack_i, -     -    // FIFO interface -    input fifo_clk, input fifo_rst, input clear_tx, input clear_rx, -    output [35:0] tx_data_o, output tx_src_rdy_o, input tx_dst_rdy_i, -    input [35:0] rx_data_i, input rx_src_rdy_i, output rx_dst_rdy_o, -     -    input [15:0] tx_frame_len, output [15:0] rx_frame_len, - -    output tx_underrun, output rx_overrun, -    input [7:0] test_rate, input [3:0] test_ctrl, -    output [31:0] debug -    ); - -   wire 	  EM_output_enable = (~EM_NOE & (~EM_NCS4 | ~EM_NCS6)); -   wire [15:0] 	  EM_D_fifo; -   wire [15:0] 	  EM_D_wb; -    -   assign EM_D = ~EM_output_enable ? 16'bz : ~EM_NCS4 ? EM_D_fifo : EM_D_wb; -    -   wire 	  bus_error_tx, bus_error_rx; -    -   always @(posedge fifo_clk) -     if(fifo_rst | clear_tx | clear_rx) -       bus_error <= 0; -     else -       bus_error <= bus_error_tx | bus_error_rx; -    -   // CS4 is RAM_2PORT for DATA PATH (high-speed data) -   //    Writes go into one RAM, reads come from the other -   // CS6 is for CONTROL PATH (wishbone) - -   // //////////////////////////////////////////// -   // TX Data Path - -   wire [17:0] 	  tx18_data, tx18b_data; -   wire 	  tx18_src_rdy, tx18_dst_rdy, tx18b_src_rdy, tx18b_dst_rdy; -   wire [15:0] 	  tx_fifo_space; -   wire [35:0] 	  tx36_data, tx_data; -   wire 	  tx36_src_rdy, tx36_dst_rdy, tx_src_rdy, tx_dst_rdy; -    -   gpmc_to_fifo_async gpmc_to_fifo_async -     (.EM_D(EM_D), .EM_NBE(EM_NBE), .EM_NCS(EM_NCS4), .EM_NWE(EM_NWE), -      .fifo_clk(fifo_clk), .fifo_rst(fifo_rst), .clear(clear_tx), -      .data_o(tx18_data), .src_rdy_o(tx18_src_rdy), .dst_rdy_i(tx18_dst_rdy), -      .frame_len(tx_frame_len), .fifo_space(tx_fifo_space), .fifo_ready(tx_have_space), -      .bus_error(bus_error_tx) ); -    -   fifo_cascade #(.WIDTH(18), .SIZE(10)) tx_fifo -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .datain(tx18_data), .src_rdy_i(tx18_src_rdy), .dst_rdy_o(tx18_dst_rdy), .space(tx_fifo_space), -      .dataout(tx18b_data), .src_rdy_o(tx18b_src_rdy), .dst_rdy_i(tx18b_dst_rdy), .occupied()); - -   fifo19_to_fifo36 #(.LE(1)) f19_to_f36   // Little endian because ARM is LE -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .f19_datain({1'b0,tx18b_data}), .f19_src_rdy_i(tx18b_src_rdy), .f19_dst_rdy_o(tx18b_dst_rdy), -      .f36_dataout(tx36_data), .f36_src_rdy_o(tx36_src_rdy), .f36_dst_rdy_i(tx36_dst_rdy)); -    -   fifo_cascade #(.WIDTH(36), .SIZE(TXFIFOSIZE)) tx_fifo36 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .datain(tx36_data), .src_rdy_i(tx36_src_rdy), .dst_rdy_o(tx36_dst_rdy), -      .dataout(tx_data), .src_rdy_o(tx_src_rdy), .dst_rdy_i(tx_dst_rdy)); - -   // //////////////////////////////////////////// -   // RX Data Path -    -   wire [17:0] 	  rx18_data, rx18b_data; -   wire 	  rx18_src_rdy, rx18_dst_rdy, rx18b_src_rdy, rx18b_dst_rdy; -   wire [15:0] 	  rx_fifo_space; -   wire [35:0] 	  rx36_data, rx_data; -   wire 	  rx36_src_rdy, rx36_dst_rdy, rx_src_rdy, rx_dst_rdy; -   wire 	  dummy; -    -   fifo_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_fifo36 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .datain(rx_data), .src_rdy_i(rx_src_rdy), .dst_rdy_o(rx_dst_rdy), -      .dataout(rx36_data), .src_rdy_o(rx36_src_rdy), .dst_rdy_i(rx36_dst_rdy)); - -   fifo36_to_fifo19 #(.LE(1)) f36_to_f19   // Little endian because ARM is LE -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .f36_datain(rx36_data), .f36_src_rdy_i(rx36_src_rdy), .f36_dst_rdy_o(rx36_dst_rdy), -      .f19_dataout({dummy,rx18_data}), .f19_src_rdy_o(rx18_src_rdy), .f19_dst_rdy_i(rx18_dst_rdy) ); - -   fifo_cascade #(.WIDTH(18), .SIZE(12)) rx_fifo -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .datain(rx18_data), .src_rdy_i(rx18_src_rdy), .dst_rdy_o(rx18_dst_rdy), .space(rx_fifo_space), -      .dataout(rx18b_data), .src_rdy_o(rx18b_src_rdy), .dst_rdy_i(rx18b_dst_rdy), .occupied()); - -   fifo_to_gpmc_async fifo_to_gpmc_async -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .data_i(rx18b_data), .src_rdy_i(rx18b_src_rdy), .dst_rdy_o(rx18b_dst_rdy), -      .EM_D(EM_D_fifo), .EM_NCS(EM_NCS4), .EM_NOE(EM_NOE), -      .frame_len(rx_frame_len) ); - -   wire [31:0] 	pkt_count; -    -   fifo_watcher fifo_watcher -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .src_rdy1(rx18_src_rdy), .dst_rdy1(rx18_dst_rdy), .sof1(rx18_data[16]), .eof1(rx18_data[17]), -      .src_rdy2(rx18b_src_rdy), .dst_rdy2(rx18b_dst_rdy), .sof2(rx18b_data[16]), .eof2(rx18b_data[17]), -      .have_packet(rx_have_data), .length(rx_frame_len), .bus_error(bus_error_rx), -      .debug(pkt_count)); - -   // //////////////////////////////////////////// -   // Control path on CS6 -    -   gpmc_wb gpmc_wb -     (.EM_CLK(EM_CLK), .EM_D_in(EM_D), .EM_D_out(EM_D_wb), .EM_A(EM_A), .EM_NBE(EM_NBE), -      .EM_NCS(EM_NCS6), .EM_NWE(EM_NWE), .EM_NOE(EM_NOE), -      .wb_clk(wb_clk), .wb_rst(wb_rst), -      .wb_adr_o(wb_adr_o), .wb_dat_mosi(wb_dat_mosi), .wb_dat_miso(wb_dat_miso), -      .wb_sel_o(wb_sel_o), .wb_cyc_o(wb_cyc_o), .wb_stb_o(wb_stb_o), .wb_we_o(wb_we_o), -      .wb_ack_i(wb_ack_i) ); -    -//      assign debug = pkt_count; - -   // //////////////////////////////////////////// -   // Test support, traffic generator, loopback, etc. - -   // RX side muxes test data into the same stream -   wire [35:0] 	timedrx_data, loopbackrx_data, testrx_data; -   wire [35:0] 	timedtx_data, loopbacktx_data, testtx_data; -   wire 	timedrx_src_rdy, timedrx_dst_rdy, loopbackrx_src_rdy, loopbackrx_dst_rdy, -		testrx_src_rdy, testrx_dst_rdy; -   wire 	timedtx_src_rdy, timedtx_dst_rdy, loopbacktx_src_rdy, loopbacktx_dst_rdy, -		testtx_src_rdy, testtx_dst_rdy; -   wire 	timedrx_src_rdy_int, timedrx_dst_rdy_int, timedtx_src_rdy_int, timedtx_dst_rdy_int; - -   wire [31:0] 	total, crc_err, seq_err, len_err; -   wire 	sel_testtx = test_ctrl[0]; -   wire 	sel_loopbacktx = test_ctrl[1]; -   wire 	pkt_src_enable = test_ctrl[2]; -   wire 	pkt_sink_enable = test_ctrl[3]; -    -   fifo36_mux rx_test_mux_lvl_1 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .data0_i(timedrx_data), .src0_rdy_i(timedrx_src_rdy), .dst0_rdy_o(timedrx_dst_rdy), -      .data1_i(loopbackrx_data), .src1_rdy_i(loopbackrx_src_rdy), .dst1_rdy_o(loopbackrx_dst_rdy), -      .data_o(testrx_data), .src_rdy_o(testrx_src_rdy), .dst_rdy_i(testrx_dst_rdy)); -    -   fifo36_mux rx_test_mux_lvl_2 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .data0_i(testrx_data), .src0_rdy_i(testrx_src_rdy), .dst0_rdy_o(testrx_dst_rdy), -      .data1_i(rx_data_i), .src1_rdy_i(rx_src_rdy_i), .dst1_rdy_o(rx_dst_rdy_o), -      .data_o(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy)); -    -   fifo_short #(.WIDTH(36)) loopback_fifo -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx | clear_rx), -      .datain(loopbacktx_data), .src_rdy_i(loopbacktx_src_rdy), .dst_rdy_o(loopbacktx_dst_rdy), -      .dataout(loopbackrx_data), .src_rdy_o(loopbackrx_src_rdy), .dst_rdy_i(loopbackrx_dst_rdy)); -    -   // Crossbar used as a demux for switching TX stream to main DSP or to test logic -   crossbar36 tx_crossbar_lvl_1 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .cross(sel_testtx), -      .data0_i(tx_data), .src0_rdy_i(tx_src_rdy), .dst0_rdy_o(tx_dst_rdy), -      .data1_i(tx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(),  // No 2nd input -      .data0_o(tx_data_o), .src0_rdy_o(tx_src_rdy_o), .dst0_rdy_i(tx_dst_rdy_i), -      .data1_o(testtx_data), .src1_rdy_o(testtx_src_rdy), .dst1_rdy_i(testtx_dst_rdy) ); -    -   crossbar36 tx_crossbar_lvl_2 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .cross(sel_loopbacktx), -      .data0_i(testtx_data), .src0_rdy_i(testtx_src_rdy), .dst0_rdy_o(testtx_dst_rdy), -      .data1_i(testtx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(),  // No 2nd input -      .data0_o(timedtx_data), .src0_rdy_o(timedtx_src_rdy), .dst0_rdy_i(timedtx_dst_rdy), -      .data1_o(loopbacktx_data), .src1_rdy_o(loopbacktx_src_rdy), .dst1_rdy_i(loopbacktx_dst_rdy) ); -    -   // Fixed rate TX traffic consumer -   fifo_pacer tx_pacer -     (.clk(fifo_clk), .reset(fifo_rst), .rate(test_rate), .enable(pkt_sink_enable), -      .src1_rdy_i(timedtx_src_rdy), .dst1_rdy_o(timedtx_dst_rdy), -      .src2_rdy_o(timedtx_src_rdy_int), .dst2_rdy_i(timedtx_dst_rdy_int), -      .underrun(tx_underrun), .overrun()); - -   packet_verifier32 pktver32 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .data_i(timedtx_data), .src_rdy_i(timedtx_src_rdy_int), .dst_rdy_o(timedtx_dst_rdy_int), -      .total(total), .crc_err(crc_err), .seq_err(seq_err), .len_err(len_err)); - -   // Fixed rate RX traffic generator -   packet_generator32 pktgen32 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .header({len_err,seq_err,crc_err,total}), -      .data_o(timedrx_data), .src_rdy_o(timedrx_src_rdy_int), .dst_rdy_i(timedrx_dst_rdy_int)); - -   fifo_pacer rx_pacer -     (.clk(fifo_clk), .reset(fifo_rst), .rate(test_rate), .enable(pkt_src_enable), -      .src1_rdy_i(timedrx_src_rdy_int), .dst1_rdy_o(timedrx_dst_rdy_int), -      .src2_rdy_o(timedrx_src_rdy), .dst2_rdy_i(timedrx_dst_rdy), -      .underrun(), .overrun(rx_overrun)); - -   // FIXME -- hook up crossbar controls -   // // FIXME -- collect error stats -   // FIXME -- set rates and enables on pacers -   // FIXME -- make sure packet completes before we shutoff -   // FIXME -- handle overrun and underrun - -wire [0:17] dummy18; - -assign debug = {8'd0, -		test_rate, -		pkt_src_enable, pkt_sink_enable, timedrx_src_rdy_int, timedrx_dst_rdy_int, -		timedrx_src_rdy, timedrx_dst_rdy, -		testrx_src_rdy, testrx_dst_rdy, -		rx_src_rdy, rx_dst_rdy, -		rx36_src_rdy, rx36_dst_rdy, -		rx18_src_rdy, rx18_dst_rdy, -		rx18b_src_rdy, rx18b_dst_rdy}; - -endmodule // gpmc_async diff --git a/fpga/usrp2/gpmc/gpmc_sync.v b/fpga/usrp2/gpmc/gpmc_sync.v deleted file mode 100644 index ba7251c8d..000000000 --- a/fpga/usrp2/gpmc/gpmc_sync.v +++ /dev/null @@ -1,125 +0,0 @@ -// -// 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 gpmc_sync -  (// GPMC signals -   input arst, -   input EM_CLK, inout [15:0] EM_D, input [10:1] EM_A, input [1:0] EM_NBE, -   input EM_WAIT0, input EM_NCS4, input EM_NCS6, input EM_NWE, input EM_NOE, -    -   // GPIOs for FIFO signalling -   output rx_have_data, output tx_have_space, output bus_error, input bus_reset, -    -   // Wishbone signals -   input wb_clk, input wb_rst, -   output [10:0] wb_adr_o, output [15:0] wb_dat_mosi, input [15:0] wb_dat_miso, -   output [1:0] wb_sel_o, output wb_cyc_o, output wb_stb_o, output wb_we_o, input wb_ack_i, - -   // FIFO interface -   input fifo_clk, input fifo_rst, -   output [35:0] tx_data_o, output tx_src_rdy_o, input tx_dst_rdy_i, -   input [35:0] rx_data_i, input rx_src_rdy_i, output rx_dst_rdy_o, - -   output [31:0] debug -   ); - -   wire 	EM_output_enable = (~EM_NOE & (~EM_NCS4 | ~EM_NCS6)); -   wire [15:0] 	EM_D_fifo; -   wire [15:0] 	EM_D_wb; - -   assign EM_D = ~EM_output_enable ? 16'bz : ~EM_NCS4 ? EM_D_fifo : EM_D_wb; - -   wire 	bus_error_tx, bus_error_rx; -   assign bus_error = bus_error_tx | bus_error_rx; -    -   // CS4 is RAM_2PORT for DATA PATH (high-speed data) -   //    Writes go into one RAM, reads come from the other -   // CS6 is for CONTROL PATH (wishbone) - -   // //////////////////////////////////////////// -   // TX Data Path - -   wire [17:0] 	tx18_data, tx18b_data; -   wire 	tx18_src_rdy, tx18_dst_rdy, tx18b_src_rdy, tx18b_dst_rdy; -   wire [15:0] 	tx_fifo_space, tx_frame_len; -    -   assign tx_frame_len = 10; -    -   gpmc_to_fifo_sync gpmc_to_fifo_sync -     (.arst(arst), -      .EM_CLK(EM_CLK), .EM_D(EM_D), .EM_NBE(EM_NBE), .EM_NCS(EM_NCS4), .EM_NWE(EM_NWE), -      .data_o(tx18_data), .src_rdy_o(tx18_src_rdy), .dst_rdy_i(tx18_dst_rdy), -      .frame_len(tx_frame_len), .fifo_space(tx_fifo_space), .fifo_ready(tx_have_space), -      .bus_error(bus_error_tx) ); -    -   fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) tx_fifo -     (.wclk(EM_CLK), .datain(tx18_data),  -      .src_rdy_i(tx18_src_rdy), .dst_rdy_o(tx18_dst_rdy), .space(tx_fifo_space), -      .rclk(fifo_clk), .dataout(tx18b_data),  -      .src_rdy_o(tx18b_src_rdy), .dst_rdy_i(tx18b_dst_rdy), .occupied(), .arst(arst)); - -   fifo19_to_fifo36 #(.LE(1)) f19_to_f36   // Little endian because ARM is LE -     (.clk(fifo_clk), .reset(fifo_rst), .clear(0), -      .f19_datain({1'b0,tx18b_data}), .f19_src_rdy_i(tx18b_src_rdy), .f19_dst_rdy_o(tx18b_dst_rdy), -      .f36_dataout(tx_data_o), .f36_src_rdy_o(tx_src_rdy_o), .f36_dst_rdy_i(tx_dst_rdy_i)); -    -   // //////////////////////////////////////////// -   // RX Data Path - -   wire [17:0] 	rx18_data, rx18b_data; -   wire 	rx18_src_rdy, rx18_dst_rdy, rx18b_src_rdy, rx18b_dst_rdy; -   wire [15:0] 	rx_fifo_space, rx_frame_len; -   wire 	dummy; -    -   fifo36_to_fifo19 #(.LE(1)) f36_to_f19   // Little endian because ARM is LE -     (.clk(fifo_clk), .reset(fifo_rst), .clear(0), -      .f36_datain(rx_data_i), .f36_src_rdy_i(rx_src_rdy_i), .f36_dst_rdy_o(rx_dst_rdy_o), -      .f19_dataout({dummy,rx18_data}), .f19_src_rdy_o(rx18_src_rdy), .f19_dst_rdy_i(rx18_dst_rdy) ); - -   fifo_2clock_cascade #(.WIDTH(18), .SIZE(10)) rx_fifo -     (.wclk(fifo_clk), .datain(rx18_data),  -      .src_rdy_i(rx18_src_rdy), .dst_rdy_o(rx18_dst_rdy), .space(rx_fifo_space), -      .rclk(EM_CLK), .dataout(rx18b_data),  -      .src_rdy_o(rx18b_src_rdy), .dst_rdy_i(rx18b_dst_rdy), .occupied(), .arst(arst)); - -   fifo_to_gpmc_sync fifo_to_gpmc_sync -     (.arst(arst), -      .data_i(rx18b_data), .src_rdy_i(rx18b_src_rdy), .dst_rdy_o(rx18b_dst_rdy), -      .EM_CLK(EM_CLK), .EM_D(EM_D_fifo), .EM_NCS(EM_NCS4), .EM_NOE(EM_NOE), -      .fifo_ready(rx_have_data) ); - -   fifo_watcher fifo_watcher -     (.clk(fifo_clk), .reset(fifo_rst), .clear(0), -      .src_rdy(rx18_src_rdy), .dst_rdy(rx18_dst_rdy), .sof(rx18_data[16]), .eof(rx18_data[17]), -      .have_packet(), .length(), .next() ); -    -   // //////////////////////////////////////////// -   // Control path on CS6 -    -   gpmc_wb gpmc_wb -     (.EM_CLK(EM_CLK), .EM_D_in(EM_D), .EM_D_out(EM_D_wb), .EM_A(EM_A), .EM_NBE(EM_NBE), -      .EM_NCS(EM_NCS6), .EM_NWE(EM_NWE), .EM_NOE(EM_NOE), -      .wb_clk(wb_clk), .wb_rst(wb_rst), -      .wb_adr_o(wb_adr_o), .wb_dat_mosi(wb_dat_mosi), .wb_dat_miso(wb_dat_miso), -      .wb_sel_o(wb_sel_o), .wb_cyc_o(wb_cyc_o), .wb_stb_o(wb_stb_o), .wb_we_o(wb_we_o), -      .wb_ack_i(wb_ack_i) ); -    -      assign debug = 0; -    -endmodule // gpmc_sync diff --git a/fpga/usrp2/gpmc/gpmc_to_fifo.v b/fpga/usrp2/gpmc/gpmc_to_fifo.v new file mode 100644 index 000000000..4aa55953a --- /dev/null +++ b/fpga/usrp2/gpmc/gpmc_to_fifo.v @@ -0,0 +1,157 @@ +// +// 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/>. +// + +//////////////////////////////////////////////////////////////////////// +// GPMC to FIFO +// +// Reads frames from BRAM pages and writes them into FIFO interface. +// The GPMC is asynchronously alerted when a BRAM page is available. +// +// EM_CLK: +// A GPMC read transaction consists of one EM_CLK cycle (idle low). +// +// EM_WE: +// Write enable is actually the combination of ~NWE & ~NCS. +// The write enable is active for the entire transaction. +// +// EM_D: +// Data is set on the rising edge and written into BRAM on the falling edge. +// +// EM_A: +// Address is set on the rising edge and read by BRAM on the falling edge. +//////////////////////////////////////////////////////////////////////// + +module gpmc_to_fifo +  #(parameter PTR_WIDTH = 2, parameter ADDR_WIDTH = 10) +  (input [15:0] EM_D, input [ADDR_WIDTH:1] EM_A, input EM_CLK, input EM_WE, +   input clk, input reset, input clear, input arst, +   output [17:0] data_o, output src_rdy_o, input dst_rdy_i, +   output reg have_space); + +    //states for the GPMC side of things +    wire [17:0] data_i; +    reg gpmc_state; +    reg [ADDR_WIDTH:1] last_addr; +    reg [PTR_WIDTH:0] gpmc_ptr, next_gpmc_ptr; +    localparam GPMC_STATE_START = 0; +    localparam GPMC_STATE_FILL = 1; + +    //states for the FIFO side of things +    reg fifo_state; +    reg [ADDR_WIDTH-1:0] counter; +    reg [PTR_WIDTH:0] fifo_ptr; +    localparam FIFO_STATE_CLAIM = 0; +    localparam FIFO_STATE_EMPTY = 1; + +    //------------------------------------------------------------------ +    // State machine to control the data from GPMC to BRAM +    //------------------------------------------------------------------ +    always @(negedge EM_CLK or posedge arst) begin +        if (arst) begin +            gpmc_state <= GPMC_STATE_START; +            gpmc_ptr <= 0; +            next_gpmc_ptr <= 0; +        end +        else if (EM_WE) begin +            case(gpmc_state) + +            GPMC_STATE_START: begin +                if (EM_A == 0) begin +                    gpmc_state <= GPMC_STATE_FILL; +                    last_addr <= {EM_D[ADDR_WIDTH-2:0], 1'b0} - 1'b1; +                    next_gpmc_ptr <= gpmc_ptr + 1; +                end +            end + +            GPMC_STATE_FILL: begin +                if (data_i[17]) begin +                    gpmc_state <= GPMC_STATE_START; +                    gpmc_ptr <= next_gpmc_ptr; +                end +            end + +            endcase //gpmc_state +        end //EM_WE +    end //always + +    //------------------------------------------------------------------ +    // A block ram is available to empty when the pointers dont match. +    //------------------------------------------------------------------ +    wire [PTR_WIDTH:0] safe_gpmc_ptr; +    cross_clock_reader #(.WIDTH(PTR_WIDTH+1)) read_gpmc_ptr +        (.clk(clk), .rst(reset | clear), .in(gpmc_ptr), .out(safe_gpmc_ptr)); + +    wire bram_available_to_empty = safe_gpmc_ptr != fifo_ptr; + +    //------------------------------------------------------------------ +    // Glich free generation of have space signal: +    // High when the fifo pointer has not caught up to the gpmc pointer. +    //------------------------------------------------------------------ +    wire [PTR_WIDTH:0] safe_next_gpmc_ptr; +    cross_clock_reader #(.WIDTH(PTR_WIDTH+1)) read_next_gpmc_ptr +        (.clk(clk), .rst(reset | clear), .in(next_gpmc_ptr), .out(safe_next_gpmc_ptr)); + +    always @(posedge clk) +        if (reset | clear) have_space <= 0; +        else               have_space <= (fifo_ptr ^ (1 << PTR_WIDTH)) != safe_next_gpmc_ptr; + +    //------------------------------------------------------------------ +    // State machine to control the data from BRAM to FIFO +    //------------------------------------------------------------------ +    always @(posedge clk) begin +        if (reset | clear) begin +            fifo_state <= FIFO_STATE_CLAIM; +            fifo_ptr <= 0; +            counter <= 0; +        end +        else begin +            case(fifo_state) + +            FIFO_STATE_CLAIM: begin +                if (bram_available_to_empty) fifo_state <= FIFO_STATE_EMPTY; +                counter <= 0; +            end + +            FIFO_STATE_EMPTY: begin +                if (src_rdy_o && dst_rdy_i && data_o[17]) begin +                    fifo_state <= FIFO_STATE_CLAIM; +                    fifo_ptr <= fifo_ptr + 1; +                end +                if (src_rdy_o && dst_rdy_i) begin +                    counter <= counter + 1; +                end +            end + +            endcase //fifo_state +        end +    end //always + +    assign src_rdy_o = fifo_state == FIFO_STATE_EMPTY; + +    //assign data and frame bits to bram input +    assign data_i[15:0] = EM_D; +    assign data_i[16] = (gpmc_state == GPMC_STATE_START); +    assign data_i[17] = (EM_A == last_addr); + +    //instantiate dual ported bram for async read + write +    ram_2port #(.DWIDTH(18),.AWIDTH(PTR_WIDTH + ADDR_WIDTH)) async_fifo_bram +     (.clka(~EM_CLK),.ena(1'b1),.wea(EM_WE), +      .addra({gpmc_ptr[PTR_WIDTH-1:0], EM_A}),.dia(data_i),.doa(), +      .clkb(~clk),.enb(1'b1),.web(1'b0), +      .addrb({fifo_ptr[PTR_WIDTH-1:0], counter}),.dib(18'h3ffff),.dob(data_o)); + +endmodule // gpmc_to_fifo diff --git a/fpga/usrp2/gpmc/gpmc_to_fifo_async.v b/fpga/usrp2/gpmc/gpmc_to_fifo_async.v deleted file mode 100644 index aa93e52af..000000000 --- a/fpga/usrp2/gpmc/gpmc_to_fifo_async.v +++ /dev/null @@ -1,85 +0,0 @@ -// -// 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 gpmc_to_fifo_async -  (input [15:0] EM_D, input [1:0] EM_NBE, input EM_NCS, input EM_NWE, - -   input fifo_clk, input fifo_rst, input clear, -   output reg [17:0] data_o, output reg src_rdy_o, input dst_rdy_i, - -   input [15:0] frame_len, input [15:0] fifo_space, output reg fifo_ready, -   output reg bus_error ); - -   reg [15:0] counter; -   // Synchronize the async control signals -   reg [1:0] 	cs_del, we_del; -   always @(posedge fifo_clk) -     if(fifo_rst) -       begin -	  cs_del <= 2'b11; -	  we_del <= 2'b11; -       end -     else -       begin -	  cs_del <= { cs_del[0], EM_NCS }; -	  we_del <= { we_del[0], EM_NWE }; -       end - -   wire do_write = (~cs_del[0] & (we_del == 2'b10)); -   wire first_write = (counter == 0); -   wire last_write = ((counter+1) == frame_len); - -   always @(posedge fifo_clk) -     if(do_write) -       begin -	  data_o[15:0] <= EM_D; -	  data_o[16] <= first_write; -	  data_o[17] <= last_write; -	  //  no byte writes data_o[18] <= |EM_NBE;  // mark half full if either is not enabled  FIXME -       end - -   always @(posedge fifo_clk) -     if(fifo_rst | clear) -       src_rdy_o <= 0; -     else if(do_write) -       src_rdy_o <= 1; -     else -       src_rdy_o <= 0;    // Assume it was taken - -   always @(posedge fifo_clk) -     if(fifo_rst | clear) -       counter <= 0; -     else if(do_write) -       if(last_write) -	 counter <= 0; -       else -	 counter <= counter + 1; - -   always @(posedge fifo_clk) -     if(fifo_rst | clear) -       fifo_ready <= 0; -     else -       fifo_ready <= /* first_write & */ (fifo_space > 16'd1023); - -   always @(posedge fifo_clk) -     if(fifo_rst | clear) -       bus_error <= 0; -     else if(src_rdy_o & ~dst_rdy_i) -       bus_error <= 1; -    -endmodule // gpmc_to_fifo_async diff --git a/fpga/usrp2/gpmc/gpmc_to_fifo_sync.v b/fpga/usrp2/gpmc/gpmc_to_fifo_sync.v deleted file mode 100644 index 7ff7afdc2..000000000 --- a/fpga/usrp2/gpmc/gpmc_to_fifo_sync.v +++ /dev/null @@ -1,74 +0,0 @@ -// -// 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/>. -// - - -// Assumes a GPMC cycle with GPMC clock, as in the timing diagrams -//   If a packet bigger or smaller than we are told is sent, behavior is undefined. -//   If dst_rdy_i is low when we get data, behavior is undefined and we signal bus error. -//   If there is a bus error, we should be reset - -module gpmc_to_fifo_sync -  (input arst, -   input EM_CLK, input [15:0] EM_D, input [1:0] EM_NBE, -   input EM_NCS, input EM_NWE, -   output reg [17:0] data_o, output reg src_rdy_o, input dst_rdy_i, -   input [15:0] frame_len, input [15:0] fifo_space, output fifo_ready,  -   output reg bus_error); -    -   reg [10:0] 	counter; -   wire 	first_write = (counter == 0); -   wire 	last_write = ((counter+1) == frame_len); -   wire 	do_write = ~EM_NCS & ~EM_NWE; -    -   always @(posedge EM_CLK or posedge arst) -     if(arst) -       data_o <= 0; -     else if(do_write) -       begin -	  data_o[15:0] <= EM_D; -	  data_o[16] <= first_write; -	  data_o[17] <= last_write; -	  //  no byte writes data_o[18] <= |EM_NBE;  // mark half full if either is not enabled  FIXME -       end - -   always @(posedge EM_CLK or posedge arst) -     if(arst) -       src_rdy_o <= 0; -     else if(do_write & ~bus_error)  // Don't put junk in if there is a bus error -       src_rdy_o <= 1; -     else -       src_rdy_o <= 0;    // Assume it was taken, ignore dst_rdy_i - -   always @(posedge EM_CLK or posedge arst) -     if(arst) -       counter <= 0; -     else if(do_write) -       if(last_write) -	 counter <= 0; -       else -	 counter <= counter + 1; - -   assign fifo_ready = first_write & (fifo_space > frame_len); -    -   always @(posedge EM_CLK or posedge arst) -     if(arst) -       bus_error <= 0; -     else if(src_rdy_o & ~dst_rdy_i) -       bus_error <= 1; -   // must be reset to make the error go away - -endmodule // gpmc_to_fifo_sync diff --git a/fpga/usrp2/gpmc/gpmc_wb.v b/fpga/usrp2/gpmc/gpmc_wb.v index 645201ef7..4d368ca94 100644 --- a/fpga/usrp2/gpmc/gpmc_wb.v +++ b/fpga/usrp2/gpmc/gpmc_wb.v @@ -19,7 +19,7 @@  module gpmc_wb    (input EM_CLK, input [15:0] EM_D_in, output [15:0] EM_D_out, input [10:1] EM_A, input [1:0] EM_NBE, -   input EM_NCS, input EM_NWE, input EM_NOE, +   input EM_WE, input EM_OE,     input wb_clk, input wb_rst,     output reg [10:0] wb_adr_o, output reg [15:0] wb_dat_mosi, input [15:0] wb_dat_miso, @@ -27,25 +27,31 @@ module gpmc_wb     // ////////////////////////////////////////////     // Control Path, Wishbone bus bridge (wb master) -   reg [1:0] 	cs_del, we_del, oe_del; +   reg [1:0] we_del, oe_del;     // Synchronize the async control signals     always @(posedge wb_clk) -     begin -	cs_del <= { cs_del[0], EM_NCS }; -	we_del <= { we_del[0], EM_NWE }; -	oe_del <= { oe_del[0], EM_NOE }; +     if (wb_rst) begin +        we_del <= 2'b0; +        oe_del <= 2'b0;       end +     else begin +        we_del <= { we_del[0], EM_WE }; +        oe_del <= { oe_del[0], EM_OE }; +     end + +    wire writing = we_del == 2'b01; +    wire reading = oe_del == 2'b01;     always @(posedge wb_clk) -     if(cs_del == 2'b10)  // Falling Edge +     if(writing || reading)         wb_adr_o <= { EM_A, 1'b0 };     always @(posedge wb_clk) -     if(we_del == 2'b10)  // Falling Edge +     if(writing)         begin -	  wb_dat_mosi <= EM_D_in; -	  wb_sel_o <= ~EM_NBE; +          wb_dat_mosi <= EM_D_in; +          wb_sel_o <= ~EM_NBE;         end     reg [15:0] EM_D_hold; @@ -59,14 +65,13 @@ module gpmc_wb     assign wb_cyc_o = wb_stb_o;     always @(posedge wb_clk) -     if(~cs_del[0] & (we_del == 2'b10) ) +     if(writing)         wb_we_o <= 1;       else if(wb_ack_i)  // Turn off we when done.  Could also use we_del[0], others...         wb_we_o <= 0; -   // FIXME should this look at cs_del[1]?     always @(posedge wb_clk) -     if(~cs_del[0] & ((we_del == 2'b10) | (oe_del == 2'b10))) +     if(writing || reading)         wb_stb_o <= 1;       else if(wb_ack_i)         wb_stb_o <= 0; diff --git a/fpga/usrp2/gpmc/make_timing_diag b/fpga/usrp2/gpmc/make_timing_diag deleted file mode 100755 index 03166ad35..000000000 --- a/fpga/usrp2/gpmc/make_timing_diag +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -drawtiming -o single_data_write.gif single_data_write.txt -drawtiming -o single_data_read.gif single_data_read.txt -drawtiming -o burst_data_write.gif burst_data_write.txt -#drawtiming -o burst_data_read.gif burst_data_read.txt - diff --git a/fpga/usrp2/gpmc/ram_to_fifo.v b/fpga/usrp2/gpmc/ram_to_fifo.v deleted file mode 100644 index 958c88b0f..000000000 --- a/fpga/usrp2/gpmc/ram_to_fifo.v +++ /dev/null @@ -1,63 +0,0 @@ -// -// 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 ram_to_fifo -  (input clk, input reset, -   input [10:0] read_length,  // From the dbsm (?) -   output read_en, output reg [8:0] read_addr, input [31:0] read_data, input read_ready, output read_done, -   output [35:0] data_o, output src_rdy_o, input dst_rdy_i); - -   // read_length/2 = number of 32 bit lines, numbered 0 through read_length/2-1 -   wire [8:0] 	 last_line = (read_length[10:1]-1);  - -   reg 		 read_phase, sop; - -   assign read_en = (read_phase == 0) | dst_rdy_i; -   assign src_rdy_o = (read_phase == 1); -    -   always @(posedge clk) -     if(reset) -       begin -	  read_addr <= 0; -	  read_phase <= 0; -	  sop <= 1; -       end -     else -       if(read_phase == 0) -	 begin -	    read_addr <= read_ready; -	    read_phase <= read_ready; -	 end -       else if(dst_rdy_i) -	 begin -	    sop <= 0; -	    if(read_addr == last_line) -	      begin -		 read_addr <= 0; -		 read_phase <= 0; -	      end -	    else -	      read_addr <= read_addr + 1; -	 end -    -   assign read_done = (read_phase == 1) & (read_addr == last_line) & dst_rdy_i; -   wire eop = (read_addr == last_line); -   assign data_o = { 2'b00, eop, sop, read_data }; -    -endmodule // ram_to_fifo diff --git a/fpga/usrp2/gpmc/single_data_read.txt b/fpga/usrp2/gpmc/single_data_read.txt deleted file mode 100644 index 1dc0e3a78..000000000 --- a/fpga/usrp2/gpmc/single_data_read.txt +++ /dev/null @@ -1,12 +0,0 @@ -# OMAP writes to FPGA -# initialize the signals -CLK=0,nWE=1,nCS=1,nOE=1,DATA=Z. -CLK=1. -CLK=0,nOE=0,nCS=0,DATA=RD_DATA. -CLK=1. -CLK=0. -CLK=1. -CLK=0,nOE=1,nCS=1,DATA=Z. -CLK=1. - - diff --git a/fpga/usrp2/gpmc/single_data_write.txt b/fpga/usrp2/gpmc/single_data_write.txt deleted file mode 100644 index 287e3e2c1..000000000 --- a/fpga/usrp2/gpmc/single_data_write.txt +++ /dev/null @@ -1,10 +0,0 @@ -# OMAP writes to FPGA -# initialize the signals -CLK=0,nWE=1,nCS=1,nOE=1,DATA=Z. -CLK=1. -CLK=0,nWE=0,nCS=0,DATA=WR_DATA. -CLK=1. -CLK=0,nWE=1,nCS=1,DATA=Z. -CLK=1. - - diff --git a/fpga/usrp2/top/B100/u1plus_core.v b/fpga/usrp2/top/B100/u1plus_core.v index 6a80eba76..b40083201 100644 --- a/fpga/usrp2/top/B100/u1plus_core.v +++ b/fpga/usrp2/top/B100/u1plus_core.v @@ -89,7 +89,7 @@ module u1plus_core        .in(set_data),.out(),.changed(global_reset));     reset_sync reset_sync_wb(.clk(wb_clk), .reset_in(rst_fpga | global_reset), .reset_out(wb_rst)); -   reset_sync reset_sync_gp(.clk(wb_clk), .reset_in(rst_fpga | global_reset), .reset_out(gpif_rst)); +   reset_sync reset_sync_gp(.clk(gpif_clk), .reset_in(rst_fpga | global_reset), .reset_out(gpif_rst));     wire [15:0] 	test_len;     // ///////////////////////////////////////////////////////////////////////////////////// diff --git a/fpga/usrp2/top/E1x0/timing.ucf b/fpga/usrp2/top/E1x0/timing.ucf index 8df28c9d3..f94685438 100644 --- a/fpga/usrp2/top/E1x0/timing.ucf +++ b/fpga/usrp2/top/E1x0/timing.ucf @@ -2,8 +2,22 @@  NET "CLK_FPGA_P" TNM_NET = "CLK_FPGA_P";  TIMESPEC "TS_clk_fpga_p" = PERIOD "CLK_FPGA_P" 15625 ps HIGH 50 %; +NET "EM_CLK" TNM_NET = "EM_CLK"; +TIMESPEC "TS_em_clk" = PERIOD "EM_CLK" 12048 ps HIGH 50 %; +#constrain GPMC IO +NET "EM_D<*>" MAXDELAY = 5 ns; +NET "EM_A<*>" MAXDELAY = 5 ns; +NET "EM_NBE<*>" MAXDELAY = 5 ns; +NET "EM_NCS4" MAXDELAY = 5 ns; +NET "EM_NCS6" MAXDELAY = 5 ns; +NET "EM_NWE" MAXDELAY = 5 ns; +NET "EM_NOE" MAXDELAY = 5 ns; +#constrain interrupt lines +NET "overo_gpio144" MAXDELAY = 5 ns; #have space +NET "overo_gpio146" MAXDELAY = 5 ns; #have data +NET "overo_gpio147" MAXDELAY = 5 ns; #have msg/aux spi miso  #NET "adc_a<*>" TNM_NET = ADC_DATA_GRP;  #NET "adc_b<*>" TNM_NET = ADC_DATA_GRP; diff --git a/fpga/usrp2/top/E1x0/u1e.v b/fpga/usrp2/top/E1x0/u1e.v index dbd6173f3..ff2e08394 100644 --- a/fpga/usrp2/top/E1x0/u1e.v +++ b/fpga/usrp2/top/E1x0/u1e.v @@ -53,32 +53,10 @@ module u1e     // /////////////////////////////////////////////////////////////////////////     // Clocking -   wire  clk_fpga, clk_fpga_in; -    +   wire  clk_fpga; +     IBUFGDS #(.IOSTANDARD("LVDS_33"), .DIFF_TERM("TRUE"))  -   clk_fpga_pin (.O(clk_fpga_in),.I(CLK_FPGA_P),.IB(CLK_FPGA_N)); - -   wire  clk_2x, dcm_rst, dcm_locked, clk_fb; -   DCM #(.CLK_FEEDBACK ( "1X" ), -	 .CLKDV_DIVIDE ( 2 ), -	 .CLKFX_DIVIDE ( 2 ), -	 .CLKFX_MULTIPLY ( 2 ), -	 .CLKIN_DIVIDE_BY_2 ( "FALSE" ), -	 .CLKIN_PERIOD ( 15.625 ), -	 .CLKOUT_PHASE_SHIFT ( "NONE" ), -	 .DESKEW_ADJUST ( "SYSTEM_SYNCHRONOUS" ), -	 .DFS_FREQUENCY_MODE ( "LOW" ), -	 .DLL_FREQUENCY_MODE ( "LOW" ), -	 .DUTY_CYCLE_CORRECTION ( "TRUE" ), -	 .FACTORY_JF ( 16'h8080 ), -	 .PHASE_SHIFT ( 0 ), -	 .STARTUP_WAIT ( "FALSE" )) -   clk_doubler (.CLKFB(clk_fb), .CLKIN(clk_fpga_in), .RST(dcm_rst),  -                .DSSEN(0), .PSCLK(0), .PSEN(0), .PSINCDEC(0), .PSDONE(),  -		.CLKDV(), .CLKFX(), .CLKFX180(),  -                .CLK2X(), .CLK2X180(),  -                .CLK0(clk_fb), .CLK90(clk_fpga), .CLK180(), .CLK270(),  -                .LOCKED(dcm_locked), .STATUS()); +   clk_fpga_pin (.O(clk_fpga),.I(CLK_FPGA_P),.IB(CLK_FPGA_N));     // /////////////////////////////////////////////////////////////////////////     // SPI diff --git a/fpga/usrp2/top/E1x0/u1e_core.v b/fpga/usrp2/top/E1x0/u1e_core.v index 8cd51fc10..20dd98a36 100644 --- a/fpga/usrp2/top/E1x0/u1e_core.v +++ b/fpga/usrp2/top/E1x0/u1e_core.v @@ -36,7 +36,7 @@ module u1e_core     output [13:0] tx_i, output [13:0] tx_q,      input [11:0] rx_i, input [11:0] rx_q,  -   input pps_in, output proc_int +   input pps_in, output reg proc_int     );     localparam TXFIFOSIZE = 13; @@ -60,7 +60,7 @@ module u1e_core     localparam SR_CLEAR_TX_FIFO = 62; // 1 reg     localparam SR_GLOBAL_RESET = 63;  // 1 reg -   wire [7:0]	COMPAT_NUM = 8'd5; +   wire [7:0]	COMPAT_NUM = 8'd6;     wire 	wb_clk = clk_fpga;     wire 	wb_rst, global_reset; @@ -102,10 +102,7 @@ module u1e_core     wire [35:0] 	 tx_data, rx_data, tx_err_data;     wire 	 tx_src_rdy, tx_dst_rdy, rx_src_rdy, rx_dst_rdy,   		 tx_err_src_rdy, tx_err_dst_rdy; -   reg [15:0] 	 tx_frame_len; -   wire [15:0] 	 rx_frame_len; -   wire 	 bus_error;     wire 	 clear_tx, clear_rx;     setting_reg #(.my_addr(SR_CLEAR_RX_FIFO), .width(1)) sr_clear_rx @@ -116,14 +113,13 @@ module u1e_core       (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),        .in(set_data),.out(),.changed(clear_tx)); -   gpmc_async #(.TXFIFOSIZE(TXFIFOSIZE), .RXFIFOSIZE(RXFIFOSIZE)) +   gpmc #(.TXFIFOSIZE(TXFIFOSIZE), .RXFIFOSIZE(RXFIFOSIZE))     gpmc (.arst(wb_rst),  	 .EM_CLK(EM_CLK), .EM_D(EM_D), .EM_A(EM_A), .EM_NBE(EM_NBE),  	 .EM_WAIT0(EM_WAIT0), .EM_NCS4(EM_NCS4), .EM_NCS6(EM_NCS6), .EM_NWE(EM_NWE),   	 .EM_NOE(EM_NOE),  	 .rx_have_data(rx_have_data), .tx_have_space(tx_have_space), -	 .bus_error(bus_error), .bus_reset(0),  	 .wb_clk(wb_clk), .wb_rst(wb_rst),  	 .wb_adr_o(m0_adr), .wb_dat_mosi(m0_dat_mosi), .wb_dat_miso(m0_dat_miso), @@ -133,8 +129,7 @@ module u1e_core  	 .fifo_clk(wb_clk), .fifo_rst(wb_rst), .clear_tx(clear_tx), .clear_rx(clear_rx),  	 .tx_data_o(tx_data), .tx_src_rdy_o(tx_src_rdy), .tx_dst_rdy_i(tx_dst_rdy),  	 .rx_data_i(rx_data), .rx_src_rdy_i(rx_src_rdy), .rx_dst_rdy_o(rx_dst_rdy), -	  -	 .tx_frame_len(tx_frame_len), .rx_frame_len(rx_frame_len), +  	 .tx_underrun(tx_underrun_gpmc), .rx_overrun(rx_overrun_gpmc),  	 .test_rate(test_rate), .test_ctrl(test_ctrl), @@ -313,8 +308,6 @@ module u1e_core     localparam REG_CGEN_CTRL = 7'd4;    // out     localparam REG_CGEN_ST = 7'd6;      // in     localparam REG_TEST = 7'd8;         // out -   localparam REG_RX_FRAMELEN = 7'd10; // in -   localparam REG_TX_FRAMELEN = 7'd12; // out     localparam REG_XFER_RATE = 7'd14;   // out     localparam REG_COMPAT = 7'd16;      // in @@ -324,7 +317,6 @@ module u1e_core  	  reg_leds <= 0;  	  reg_cgen_ctrl <= 2'b11;  	  reg_test <= 0; -	  tx_frame_len <= 0;  	  xfer_rate <= 0;         end       else @@ -336,8 +328,6 @@ module u1e_core  	     reg_cgen_ctrl <= s0_dat_mosi;  	   REG_TEST :  	     reg_test <= s0_dat_mosi; -	   REG_TX_FRAMELEN : -	     tx_frame_len <= s0_dat_mosi;  	   REG_XFER_RATE :  	     xfer_rate <= s0_dat_mosi;  	 endcase // case (s0_adr[6:0]) @@ -352,7 +342,6 @@ module u1e_core  			(s0_adr[6:0] == REG_CGEN_CTRL) ? reg_cgen_ctrl :  			(s0_adr[6:0] == REG_CGEN_ST) ? {13'b0,cgen_st_status,cgen_st_ld,cgen_st_refmon} :  			(s0_adr[6:0] == REG_TEST) ? reg_test : -			(s0_adr[6:0] == REG_RX_FRAMELEN) ? rx_frame_len :  			(s0_adr[6:0] == REG_COMPAT) ? { 8'd0, COMPAT_NUM } :  			16'hBEEF; @@ -433,7 +422,7 @@ module u1e_core          // Wishbone interface to RAM          .wb_clk_i(wb_clk), .wb_rst_i(wb_rst),          .wb_we_i(s5_we),   .wb_stb_i(s5_stb), -        .wb_adr_i(s5_adr), .wb_dat_i({16'b0, s5_dat_mosi}), +        .wb_adr_i({5'b0,s5_adr}), .wb_dat_i({16'b0, s5_dat_mosi}),          .wb_dat_o(err_data32), .wb_ack_o(s5_ack),          // Write FIFO Interface          .wr_data_i(_tx_err_data), .wr_ready_i(_tx_err_src_rdy), .wr_ready_o(_tx_err_dst_rdy), @@ -444,7 +433,8 @@ module u1e_core     ////////////////////////////////////////////////////////////////////////////     // Interrupts -   assign proc_int = (|err_status[1:0]); +   always @(posedge wb_clk) +     proc_int <= (|err_status[1:0]);     // /////////////////////////////////////////////////////////////////////////     // Settings Bus -- Slave #8 + 9 diff --git a/fpga/usrp2/top/Makefile.common b/fpga/usrp2/top/Makefile.common index 3a35e71e7..3b71e7b13 100644 --- a/fpga/usrp2/top/Makefile.common +++ b/fpga/usrp2/top/Makefile.common @@ -36,7 +36,6 @@ synth: $(ISE_FILE)  	$(ISE_HELPER) "Synthesize - XST"  bin: check $(BIN_FILE) -	$(ISE_HELPER) "Generate Programming File"  	$(TIMING_CHECKER) $(TWR_FILE)  mcs: $(MCS_FILE) diff --git a/fpga/usrp2/top/python/check_timing.py b/fpga/usrp2/top/python/check_timing.py index c57e889d0..0c5918096 100755 --- a/fpga/usrp2/top/python/check_timing.py +++ b/fpga/usrp2/top/python/check_timing.py @@ -21,10 +21,13 @@ import re  def print_timing_constraint_summary(twr_file):      output = ""      keep = False +    done = False      for line in open(twr_file).readlines():          if 'Derived Constraint Report' in line: keep = True +        if 'constraint' in line and 'met' in line: done = True +        if not keep and done: keep = True          if keep: output += line -        if 'constraint' in line and 'met' in line: break +        if done: break      print("\n\n"+output)  if __name__=='__main__': map(print_timing_constraint_summary, sys.argv[1:]) | 
