diff options
| author | Josh Blum <josh@joshknows.com> | 2012-07-16 20:33:07 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2012-07-16 20:33:07 -0700 | 
| commit | febc5e2a684312f9a050bcf58fd13b2b42f38047 (patch) | |
| tree | 386979b5bc9728d45d3cb9e5134e0b4e4251f21c | |
| parent | c587f0204a68be1ca963bed565606d51f22fa94b (diff) | |
| download | uhd-febc5e2a684312f9a050bcf58fd13b2b42f38047.tar.gz uhd-febc5e2a684312f9a050bcf58fd13b2b42f38047.tar.bz2 uhd-febc5e2a684312f9a050bcf58fd13b2b42f38047.zip  | |
gpmc: tighter timing constraints and easier to route gpmc to fifo
| -rw-r--r-- | usrp2/gpmc/gpmc_to_fifo.v | 37 | ||||
| -rw-r--r-- | usrp2/top/E1x0/timing.ucf | 26 | 
2 files changed, 37 insertions, 26 deletions
diff --git a/usrp2/gpmc/gpmc_to_fifo.v b/usrp2/gpmc/gpmc_to_fifo.v index cfc5aaa8b..043ec9b6b 100644 --- a/usrp2/gpmc/gpmc_to_fifo.v +++ b/usrp2/gpmc/gpmc_to_fifo.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 @@ -22,7 +22,7 @@  // 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). +// A GPMC write transaction consists of one EM_CLK cycle (idle low).  //  // EM_WE:  // Write enable is actually the combination of ~NWE & ~NCS. @@ -45,17 +45,20 @@ module gpmc_to_fifo      //states for the GPMC side of things      wire [17:0] data_i;      reg gpmc_state; -    reg [ADDR_WIDTH:1] last_addr; +    reg [15:0] vita_len; +    reg [ADDR_WIDTH:1] addr; +    wire [ADDR_WIDTH:1] last_addr = {vita_len[ADDR_WIDTH-2:0], 1'b0} - 1'b1 + 2;      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 [1:0] fifo_state;      reg [ADDR_WIDTH-1:0] counter;      reg [PTR_WIDTH:0] fifo_ptr;      localparam FIFO_STATE_CLAIM = 0;      localparam FIFO_STATE_EMPTY = 1; +    localparam FIFO_STATE_PRE = 2;      //------------------------------------------------------------------      // State machine to control the data from GPMC to BRAM @@ -65,14 +68,16 @@ module gpmc_to_fifo              gpmc_state <= GPMC_STATE_START;              gpmc_ptr <= 0;              next_gpmc_ptr <= 0; +            addr <= 0;          end          else if (EM_WE) begin +            addr <= EM_A + 1;              case(gpmc_state)              GPMC_STATE_START: begin                  if (EM_A == 2) begin                      gpmc_state <= GPMC_STATE_FILL; -                    last_addr <= {EM_D[ADDR_WIDTH-2:0], 1'b0} - 1'b1 + 2; +                    vita_len <= EM_D;                      next_gpmc_ptr <= gpmc_ptr + 1;                  end              end @@ -81,6 +86,7 @@ module gpmc_to_fifo                  if (data_i[17]) begin                      gpmc_state <= GPMC_STATE_START;                      gpmc_ptr <= next_gpmc_ptr; +                    addr <= 0;                  end              end @@ -105,6 +111,7 @@ module gpmc_to_fifo      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)); +    wire [PTR_WIDTH:0] fifo_ptr_next = fifo_ptr + 1;      always @(posedge clk)          if (reset | clear) have_space <= 0;          else               have_space <= (fifo_ptr ^ (1 << PTR_WIDTH)) != safe_next_gpmc_ptr; @@ -122,16 +129,22 @@ module gpmc_to_fifo              case(fifo_state)              FIFO_STATE_CLAIM: begin -                if (bram_available_to_empty) fifo_state <= FIFO_STATE_EMPTY; +                if (bram_available_to_empty && data_o[16]) fifo_state <= FIFO_STATE_PRE;                  counter <= 2;              end +            FIFO_STATE_PRE: begin +                fifo_state <= FIFO_STATE_EMPTY; +                counter <= counter + 1; +            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; +                    counter <= 2;                  end -                if (src_rdy_o && dst_rdy_i) begin +                else if (src_rdy_o && dst_rdy_i) begin                      counter <= counter + 1;                  end              end @@ -140,18 +153,20 @@ module gpmc_to_fifo          end      end //always +    wire enable = (fifo_state != FIFO_STATE_EMPTY) || dst_rdy_i; +      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); +    assign data_i[16] = (addr == 2); +    assign data_i[17] = (addr == 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), +      .addra({gpmc_ptr[PTR_WIDTH-1:0], addr}),.dia(data_i),.doa(), +      .clkb(clk),.enb(enable),.web(1'b0),        .addrb({fifo_ptr[PTR_WIDTH-1:0], counter}),.dib(18'h3ffff),.dob(data_o));  endmodule // gpmc_to_fifo diff --git a/usrp2/top/E1x0/timing.ucf b/usrp2/top/E1x0/timing.ucf index 47c250c2f..16f06dab7 100644 --- a/usrp2/top/E1x0/timing.ucf +++ b/usrp2/top/E1x0/timing.ucf @@ -3,25 +3,21 @@ 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 %; +TIMESPEC "TS_em_clk" = PERIOD "EM_CLK" 18867 ps HIGH 50 %;  #constrain GPMC IO -NET "EM_D<*>" MAXDELAY = 5.5 ns; -NET "EM_A<*>" MAXDELAY = 5.5 ns; -NET "EM_NBE<*>" MAXDELAY = 5.5 ns; -NET "EM_NCS4" MAXDELAY = 5.5 ns; -NET "EM_NCS6" MAXDELAY = 5.5 ns; -NET "EM_NWE" MAXDELAY = 5.5 ns; -NET "EM_NOE" MAXDELAY = 5.5 ns; +INST "EM_D<*>" TNM = gpmc_net_out; +INST "EM_D<*>" TNM = gpmc_net; +INST "EM_A<*>" TNM = gpmc_net; +INST "EM_NCS4" TNM = gpmc_net; +INST "EM_NCS6" TNM = gpmc_net; +INST "EM_NWE" TNM = gpmc_net; +INST "EM_NOE" TNM = gpmc_net; + +TIMEGRP "gpmc_net" OFFSET = IN 5 ns VALID 10 ns BEFORE "EM_CLK" FALLING; +TIMEGRP "gpmc_net_out" OFFSET = OUT 14 ns AFTER "EM_CLK" RISING; //2 clock cyc per read  #constrain interrupt lines  NET "overo_gpio144" MAXDELAY = 5.5 ns; #have space  NET "overo_gpio146" MAXDELAY = 5.5 ns; #have data  NET "overo_gpio147" MAXDELAY = 5.5 ns; #have msg/aux spi miso - -#NET "adc_a<*>" TNM_NET = ADC_DATA_GRP; -#NET "adc_b<*>" TNM_NET = ADC_DATA_GRP; -#TIMEGRP "ADC_DATA_GRP" OFFSET = IN 1 ns VALID 5 ns BEFORE "clk_fpga_p" RISING; - -#NET "adc_a<*>" OFFSET = IN 1 ns VALID 5 ns BEFORE "clk_fpga_p" RISING; -#NET "adc_b<*>" OFFSET = IN 1 ns VALID 5 ns BEFORE "clk_fpga_p" RISING;  | 
