Commit 7194dbb0 authored by Andrey Filippov's avatar Andrey Filippov

replaced elastic buffer, simulated, tested

parent 0c64eabc
......@@ -52,87 +52,87 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160203212454764.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160204125242916.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160203212454764.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160204125242916.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160203212454764.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160204125242916.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160203212454764.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160204125242916.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160203212454764.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160204125242916.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160203212454764.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160204125242916.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160203212221686.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160204124820270.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160203212454764.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160204125242916.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160203212221686.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160204124820270.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160203212454764.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160204125242916.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160203212221686.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160204124820270.log</location>
</link>
<link>
<name>vivado_state/x393_sata-opt-phys.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160203212454764.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160204125242916.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-opt-power.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160203212454764.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160204125242916.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-opt.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160203212454764.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160204125242916.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-place.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160203212454764.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160204125242916.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-route.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160203212454764.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160204125242916.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-synth.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160203212221686.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160204124820270.dcp</location>
</link>
</linkedResources>
</projectDescription>
/*******************************************************************************
* Module: elastic1632
* Date:2016-02-03
* Author: andrey
* Description: Elastic buffer with 16-bit data input and 32-bit output
*
* Copyright (c) 2016 Elphel, Inc .
* elastic1632.v 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.
*
* elastic1632.v 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/> .
*******************************************************************************/
`timescale 1ns/1ps
module elastic1632#(
parameter DEPTH_LOG2 = 4, // => 16 total rows x16 is for free in Xilinx, but keep it asymmetrical to reduce
// latency
parameter OFFSET = 5 // distance between read and write pointers, = wr_ptr - rd_ptr
)(
input wclk,
input rclk,
input isaligned_in,
input [1:0] charisk_in,
input [1:0] notintable_in,
input [1:0] disperror_in,
input [15:0] data_in,
output isaligned_out,
output reg [3:0] charisk_out,
output reg [3:0] notintable_out,
output reg [3:0] disperror_out,
output reg [31:0] data_out,
// status outputs, just in case
output full,
output empty
);
localparam ALIGN_PRIM = 32'h7B4A4ABC;
localparam FIFO_DEPTH = 1 << DEPTH_LOG2;
localparam CORR_OFFSET = OFFSET - 0;
reg [15:0] data_in_r;
reg [1:0] charisk_in_r;
reg [1:0] notintable_in_r;
reg [1:0] disperror_in_r;
reg aligned32_in_r; // input data is word-aligned and got ALIGNp
reg msb_in_r; // input contains MSB
reg inc_waddr;
reg [DEPTH_LOG2:0] waddr;
wire [DEPTH_LOG2-1:0] waddr_minus = waddr[DEPTH_LOG2-1:0] - 1;
reg [DEPTH_LOG2:0] raddr;
reg [44:0] fifo_ram [0: FIFO_DEPTH -1];
reg [0:0] prealign_ram[0: FIFO_DEPTH -1];
reg [FIFO_DEPTH-1:0] fill;
wire [FIFO_DEPTH-1:0] fill_out;
wire [FIFO_DEPTH-1:0] fill_1;
reg [2:0] aligned_rclk;
reg [1:0] dav_rclk;
wire skip_rclk;
wire add_rclk;
wire [44:0] rdata = fifo_ram[raddr[DEPTH_LOG2-1:0]];
wire align_out = rdata[44];
wire pre_align_out = prealign_ram[raddr[DEPTH_LOG2-1:0]];
reg align_out_r;
reg [2:0] correct_r;
wire correct = align_out && (!align_out_r || (pre_align_out && !correct_r[2]));
reg [1:0] full_0; // full at waddr = waddr
reg [1:0] full_1; // full at waddr = raddr+1
wire is_alignp_w = ({data_in, data_in_r} == ALIGN_PRIM) &&
({charisk_in, charisk_in_r} == 4'h1) &&
({notintable_in, notintable_in_r} == 0) &&
({disperror_in, disperror_in_r} == 0);
wire [DEPTH_LOG2:0] dbg_diff = waddr-raddr;
wire dbg_dav1 = dav_rclk[1];
wire dbg_full0 = full_0[1];
wire dbg_full1 = full_1[1];
genvar ii;
generate
for (ii = 0; ii < FIFO_DEPTH; ii = ii + 1)
begin: gen_fill_out
assign fill_out[ii] = fill[(ii + CORR_OFFSET) & (FIFO_DEPTH-1)] ^ ((ii + CORR_OFFSET)>=FIFO_DEPTH);
assign fill_1[ii] = fill[(ii + 1) & (FIFO_DEPTH-1)] ^ ((ii + 1)>=FIFO_DEPTH);
end
endgenerate
// FIFO write clock domain - read data synchronous, 150MHz for SATA2
always @(posedge wclk) begin
data_in_r <= data_in;
charisk_in_r <= charisk_in;
notintable_in_r <= notintable_in;
disperror_in_r <= disperror_in;
if (!isaligned_in) aligned32_in_r <= 0;
else if (is_alignp_w) aligned32_in_r <= 1;
if (!aligned32_in_r && !is_alignp_w) msb_in_r <= 1;
else msb_in_r <= !msb_in_r;
inc_waddr <= !msb_in_r || (is_alignp_w && !aligned32_in_r);
if (!aligned32_in_r) waddr <= 0;
else if (inc_waddr) waddr <= waddr + 1;
// write will be active before aligned32_in_r too
if (msb_in_r) fifo_ram[waddr[DEPTH_LOG2-1:0]] <= {is_alignp_w,
disperror_in, disperror_in_r,
notintable_in, notintable_in_r,
charisk_in, charisk_in_r,
data_in, data_in_r};
if (msb_in_r) prealign_ram[waddr_minus] <= is_alignp_w;
if (!aligned32_in_r) fill <= 0;
else if (msb_in_r) fill <={fill[FIFO_DEPTH-2:0],~waddr[DEPTH_LOG2]};
end
// FIFO read clock domain - system synchronous, 75MHz for SATA2
always @(posedge rclk) begin
if (!aligned32_in_r) aligned_rclk <= 0;
else aligned_rclk <= {aligned_rclk[1:0],fill[OFFSET-2] | aligned_rclk[0]};
if (!aligned32_in_r) dav_rclk <= 0;
else dav_rclk <= {dav_rclk[0],fill_out[raddr[DEPTH_LOG2-1:0]] ^ raddr[DEPTH_LOG2]};
if (!aligned32_in_r) full_0 <= 1;
else full_0 <= {full_0[0], fill[raddr[DEPTH_LOG2-1:0]] ^ raddr[DEPTH_LOG2]};
if (!aligned32_in_r) full_1 <= 1;
else full_1 <= {full_1[0], fill_1[raddr[DEPTH_LOG2-1:0]] ^ raddr[DEPTH_LOG2]};
if (!aligned_rclk[1]) raddr <=0;
else if (!add_rclk) raddr <= raddr + (skip_rclk ? 2 : 1);
disperror_out <= rdata[43:40];
notintable_out <= rdata[39:36];
charisk_out <= rdata[35:32];
data_out <= rdata[31: 0];
align_out_r <= align_out;
if (correct || !aligned_rclk) correct_r <= ~0;
else correct_r <= correct_r << 1;
end
assign skip_rclk = correct && dav_rclk[1];
assign add_rclk = correct && !dav_rclk[1];
assign isaligned_out = aligned_rclk[2];
assign full = full_1[1] && !full_0[1];
assign empty = !full_1[1] && full_0[1];
endmodule
This diff is collapsed.
eclipse.preferences.version=1
encoding/create_ahci_registers.py=utf-8
This diff is collapsed.
......@@ -325,6 +325,86 @@ wire rxp;
wire txn;
wire txp;
wire device_rst;
localparam TEST_ELASTIC_PERIOD_SLOW = 13.40;
localparam TEST_ELASTIC_PERIOD_FAST = 13.27;
wire test_elastic_wclk = dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.xclk;
//wire test_elastic_rclk = dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxusrclk2;
wire test_elastic_isaligned_in = dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.state_aligned && dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxdlysresetdone_r;
wire [1:0] test_elastic_charisk_in = dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxcharisk_dec_out;
wire [1:0] test_elastic_notintable_in = dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxnotintable_dec_out;
wire [1:0] test_elastic_disperror_in = dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxdisperr_dec_out;
wire [15:0] test_elastic_data_in = dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxdata_dec_out;
wire test_elastic_slow_isaligned_out;
wire [3:0] test_elastic_slow_charisk_out;
wire [3:0] test_elastic_slow_notintable_out;
wire [3:0] test_elastic_slow_disperror_out;
wire [31:0] test_elastic_slow_data_out;
wire test_elastic_slow_full;
wire test_elastic_slow_empty;
wire test_elastic_fast_isaligned_out;
wire [3:0] test_elastic_fast_charisk_out;
wire [3:0] test_elastic_fast_notintable_out;
wire [3:0] test_elastic_fast_disperror_out;
wire [31:0] test_elastic_fast_data_out;
wire test_elastic_fast_full;
wire test_elastic_fast_empty;
reg test_elastic_slow_rclk = 0;
reg test_elastic_fast_rclk = 0;
always #(TEST_ELASTIC_PERIOD_SLOW/2) test_elastic_slow_rclk =!test_elastic_slow_rclk;
always #(TEST_ELASTIC_PERIOD_FAST/2) test_elastic_fast_rclk =!test_elastic_fast_rclk;
elastic1632 #(
.DEPTH_LOG2(4),
.OFFSET(5)
) elastic1632_slow_i (
.wclk (test_elastic_wclk), // input
.rclk (test_elastic_slow_rclk), // input
.isaligned_in (test_elastic_isaligned_in), // input
.charisk_in (test_elastic_charisk_in), // input[1:0]
.notintable_in (test_elastic_notintable_in), // input[1:0]
.disperror_in (test_elastic_disperror_in), // input[1:0]
.data_in (test_elastic_data_in), // input[15:0]
.isaligned_out (test_elastic_slow_isaligned_out), // output
.charisk_out (test_elastic_slow_charisk_out), // output[3:0] reg
.notintable_out (test_elastic_slow_notintable_out), // output[3:0] reg
.disperror_out (test_elastic_slow_disperror_out), // output[3:0] reg
.data_out (test_elastic_slow_data_out), // output[31:0] reg
.full (test_elastic_slow_full), // output
.empty (test_elastic_slow_empty) // output
);
elastic1632 #(
.DEPTH_LOG2(4),
.OFFSET(5)
) elastic1632_fast_i (
.wclk (test_elastic_wclk), // input
.rclk (test_elastic_fast_rclk), // input
.isaligned_in (test_elastic_isaligned_in), // input
.charisk_in (test_elastic_charisk_in), // input[1:0]
.notintable_in (test_elastic_notintable_in), // input[1:0]
.disperror_in (test_elastic_disperror_in), // input[1:0]
.data_in (test_elastic_data_in), // input[15:0]
.isaligned_out (test_elastic_fast_isaligned_out), // output
.charisk_out (test_elastic_fast_charisk_out), // output[3:0] reg
.notintable_out (test_elastic_fast_notintable_out), // output[3:0] reg
.disperror_out (test_elastic_fast_disperror_out), // output[3:0] reg
.data_out (test_elastic_fast_data_out), // output[31:0] reg
.full (test_elastic_fast_full), // output
.empty (test_elastic_fast_empty) // output
);
top dut(
.RXN (rxn),
.RXP (rxp),
......@@ -1116,7 +1196,7 @@ end
initial begin
// #30000;
#60000;
#70000;
// #29630;
// #30000;
// #250000;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment