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; |