jesd204: ilas_mem: Rework to be more Altera friendly

Currently the ILAS memory for the receive register map uses a shift
register with variable tap output for storing the ILAS information. This
maps very efficiently onto the primitives found in Xilinx FPGAs. But there
is no equivalent primitive in Altera FPAGs resulting in increased
utilization from having to implement the structure in pure logic.

Change the ILAS memory so it uses a simple dual port RAM for storing the
data. This has slightly increased utilization on Xilinx platforms (but
still good enough) and highly decreased utilization on Altera platforms.

One side effect of this change is that since the RAM output is synchronous
reading the ILAS memory registers will take one extra clock cycle.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
main
Lars-Peter Clausen 2017-07-21 15:04:45 +02:00
parent 2d2477e552
commit f730f14d16
5 changed files with 52 additions and 16 deletions

View File

@ -106,6 +106,7 @@ localparam PCORE_MAGIC = 32'h32303452; // 204R
reg [31:0] up_rdata = 'h0; reg [31:0] up_rdata = 'h0;
reg up_wack = 1'b0; reg up_wack = 1'b0;
reg up_rack = 1'b0; reg up_rack = 1'b0;
reg up_rreq_d1 = 1'b0;
wire up_wreq; wire up_wreq;
wire up_rreq; wire up_rreq;
wire [31:0] up_wdata; wire [31:0] up_wdata;
@ -243,6 +244,7 @@ jesd204_up_rx #(
.core_clk(core_clk), .core_clk(core_clk),
.core_reset(core_reset), .core_reset(core_reset),
.up_rreq(up_rreq),
.up_raddr(up_raddr), .up_raddr(up_raddr),
.up_rdata(up_rdata_rx), .up_rdata(up_rdata_rx),
.up_wreq(up_wreq), .up_wreq(up_wreq),
@ -266,8 +268,12 @@ jesd204_up_rx #(
always @(posedge s_axi_aclk) begin always @(posedge s_axi_aclk) begin
up_wack <= up_wreq; up_wack <= up_wreq;
up_rack <= up_rreq;
if (up_rreq == 1'b1) begin // ILAS memory takes one clock cycle before the data is ready, hence the extra
// delay.
up_rreq_d1 <= up_rreq;
up_rack <= up_rreq_d1;
if (up_rreq_d1 == 1'b1) begin
up_rdata <= up_rdata_common | up_rdata_sysref | up_rdata_rx; up_rdata <= up_rdata_common | up_rdata_sysref | up_rdata_rx;
end end
end end

View File

@ -96,8 +96,8 @@ set_false_path \
-to [get_pins {i_up_rx/*i_up_rx_lane/i_ilas_mem/i_cdc_ilas_ready/cdc_sync_stage1_reg[0]/D}] -to [get_pins {i_up_rx/*i_up_rx_lane/i_ilas_mem/i_cdc_ilas_ready/cdc_sync_stage1_reg[0]/D}]
set_max_delay -datapath_only \ set_max_delay -datapath_only \
-from [get_pins {i_up_rx/*i_up_rx_lane/i_ilas_mem/*mem_reg*/CLK}] \ -from [get_pins {i_up_rx/gen_lane[*].i_up_rx_lane/i_ilas_mem/mem_reg_*/*/CLK}] \
-to [get_pins {up_rdata_reg[*]/D}] \ -to [get_pins {i_up_rx/gen_lane[*].i_up_rx_lane/i_ilas_mem/up_rdata_reg[*]/D}] \
[get_property -min PERIOD $axi_clk] [get_property -min PERIOD $axi_clk]
set_false_path \ set_false_path \

View File

@ -45,8 +45,9 @@
module jesd204_up_ilas_mem ( module jesd204_up_ilas_mem (
input up_clk, input up_clk,
input up_rreq,
input [1:0] up_raddr, input [1:0] up_raddr,
output [31:0] up_rdata, output reg [31:0] up_rdata,
input core_clk, input core_clk,
input core_reset, input core_reset,
@ -58,7 +59,7 @@ module jesd204_up_ilas_mem (
output up_ilas_ready output up_ilas_ready
); );
reg [3:0] mem[0:31]; reg [31:0] mem[0:3];
reg core_ilas_captured = 1'b0; reg core_ilas_captured = 1'b0;
sync_bits i_cdc_ilas_ready ( sync_bits i_cdc_ilas_ready (
@ -68,6 +69,40 @@ sync_bits i_cdc_ilas_ready (
.out(up_ilas_ready) .out(up_ilas_ready)
); );
always @(posedge core_clk) begin
if (core_reset == 1'b1) begin
core_ilas_captured <= 1'b0;
end else begin
if (core_ilas_config_valid == 1'b1 && core_ilas_config_addr == 'h3) begin
core_ilas_captured <= 1'b1;
end
end
end
always @(posedge up_clk) begin
if (up_rreq == 1'b1) begin
up_rdata <= mem[up_raddr];
end
end
always @(posedge core_clk) begin
if (core_ilas_config_valid == 1'b1) begin
mem[core_ilas_config_addr] <= core_ilas_config_data;
end
end
/*
* Shift register with variable tap for accessing the stored data.
*
* This has slightly better utilization on Xilinx based platforms than the dual
* port RAM approach, but there is no equivalent primitive on Altera resulting
* in increased utilization since it needs to be implemented used registers and
* muxes.
*
* We might make this a device dependent configuration option at some point.
reg [3:0] mem[0:31];
generate generate
genvar i; genvar i;
for (i = 0; i < 32; i = i + 1) begin: gen_ilas_mem for (i = 0; i < 32; i = i + 1) begin: gen_ilas_mem
@ -80,15 +115,6 @@ for (i = 0; i < 32; i = i + 1) begin: gen_ilas_mem
end end
end end
endgenerate endgenerate
*/
always @(posedge core_clk) begin
if (core_reset == 1'b1) begin
core_ilas_captured <= 1'b0;
end else begin
if (core_ilas_config_valid == 1'b1 && core_ilas_config_addr == 'h3) begin
core_ilas_captured <= 1'b1;
end
end
end
endmodule endmodule

View File

@ -49,6 +49,7 @@ module jesd204_up_rx # (
input up_reset, input up_reset,
input up_reset_synchronizer, input up_reset_synchronizer,
input up_rreq,
input [11:0] up_raddr, input [11:0] up_raddr,
output reg [31:0] up_rdata, output reg [31:0] up_rdata,
input up_wreq, input up_wreq,
@ -148,6 +149,7 @@ generate for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
.up_clk(up_clk), .up_clk(up_clk),
.up_reset_synchronizer(up_reset_synchronizer), .up_reset_synchronizer(up_reset_synchronizer),
.up_rreq(up_rreq),
.up_raddr(up_raddr[2:0]), .up_raddr(up_raddr[2:0]),
.up_rdata(up_lane_rdata[i]), .up_rdata(up_lane_rdata[i]),

View File

@ -46,6 +46,7 @@ module jesd204_up_rx_lane (
input up_clk, input up_clk,
input up_reset_synchronizer, input up_reset_synchronizer,
input up_rreq,
input [2:0] up_raddr, input [2:0] up_raddr,
output reg [31:0] up_rdata, output reg [31:0] up_rdata,
@ -121,6 +122,7 @@ end
jesd204_up_ilas_mem i_ilas_mem ( jesd204_up_ilas_mem i_ilas_mem (
.up_clk(up_clk), .up_clk(up_clk),
.up_rreq(up_rreq),
.up_raddr(up_raddr[1:0]), .up_raddr(up_raddr[1:0]),
.up_rdata(up_ilas_rdata), .up_rdata(up_ilas_rdata),
.up_ilas_ready(up_ilas_ready), .up_ilas_ready(up_ilas_ready),