Commit 90a85abd authored by Andrey Filippov's avatar Andrey Filippov

trying to clean up resynchronization, make async reset propagate to control...

trying to clean up resynchronization, make async reset propagate to control outputs even with no clocks
parent e150ca2f
......@@ -46,7 +46,7 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20151221195334703.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20151222105615706.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
......
This diff is collapsed.
......@@ -129,7 +129,61 @@ generate
if (DATA_BYTE_WIDTH == 4) begin
// resync to txusrclk
// 2*Fin = Fout => WIDTHin = 2*WIDTHout
wire txdata_resync_nempty;
// Andrey:
reg txdata_resync_strobe;
reg [15:0] txdata_enc_in_r;
reg [ 1:0] txcharisk_enc_in_r;
wire [38:0] txdata_resync_out;
wire txdata_resync_valid;
reg txcomwake_gtx_f;
reg txcominit_gtx_f;
reg txelecidle_gtx_f;
resync_data #( // TODO: update output register.. OK as it is
.DATA_WIDTH(39),
.DATA_DEPTH(3),
.INITIAL_VALUE(39'h4000000000) // All 0 but txelecidle_gtx
) txdata_resynchro (
.arst (txreset), // input
.srst (~wrap_txreset_), // input
.wclk (txusrclk2), // input
.rclk (txusrclk), // input
.we (1'b1), // input
.re (txdata_resync_strobe), // input
.data_in ({txelecidle, txcominit, txcomwake, txcharisk, txdata}), // input[15:0]
.data_out (txdata_resync_out), // output[15:0] reg
.valid (txdata_resync_valid) // output reg
);
always @ (posedge txreset or posedge txusrclk) begin
if (txreset) txdata_resync_strobe <= 0;
else if (txdata_resync_valid) txdata_resync_strobe <= ~txdata_resync_strobe[0];
if (txreset) begin
txdata_enc_in_r <= 0;
txcharisk_enc_in_r <= 0;
end else if (txdata_resync_valid) begin
txdata_enc_in_r <= txdata_resync_strobe? txdata_resync_out[31:16]: txdata_resync_out[15:0];
txcharisk_enc_in_r <= txdata_resync_strobe? txdata_resync_out[35:34]: txdata_resync_out[33:32];
end
if (txreset) begin
txcomwake_gtx_f <= 0;
txcominit_gtx_f <= 0;
txelecidle_gtx_f <= 0;
end else begin
txcomwake_gtx_f <= txdata_resync_out[36];
txcominit_gtx_f <= txdata_resync_out[37];
txelecidle_gtx_f <= txdata_resync_out[38];
end
end
assign txdata_enc_in = txdata_enc_in_r;
assign txcharisk_enc_in = txcharisk_enc_in_r;
assign txcominit_gtx = txcominit_gtx_f;
assign txcomwake_gtx = txcomwake_gtx_f;
assign txelecidle_gtx = txelecidle_gtx_f;
/*wire txdata_resync_nempty;
reg txdata_resync_nempty_r;
reg txdata_resync_nempty_rr;
reg txdata_resync_strobe;
......@@ -138,13 +192,14 @@ if (DATA_BYTE_WIDTH == 4) begin
assign txdata_enc_in = {16{~txdata_resync_strobe}} & txdata_resync[15:0] | {16{txdata_resync_strobe}} & txdata_resync[31:16];
assign txcharisk_enc_in = {2{~txdata_resync_strobe}} & txdata_resync[33:32] | {2{txdata_resync_strobe}} & txdata_resync[35:34];
// Andrey: wrap_txreset_ has different clock domain
always @ (posedge txusrclk)
begin
txdata_resync <= ~wrap_txreset_ ? 36'h0 : txdata_resync_nempty & txdata_resync_strobe ? txdata_resync_out[35:0] : txdata_resync;
txdata_resync_strobe <= ~wrap_txreset_ ? 1'b0 : ~txdata_resync_nempty ? txdata_resync_strobe : ~txdata_resync_strobe; // -> 1 once every resynced dword = signal to latch it
txdata_resync <= ~wrap_txreset_ ? 36'h0 : ((txdata_resync_nempty & txdata_resync_strobe) ? txdata_resync_out[35:0] : txdata_resync);
txdata_resync_strobe <= ~wrap_txreset_ ? 1'b0 : ((~txdata_resync_nempty) ? txdata_resync_strobe : ~txdata_resync_strobe); // -> 1 once every resynced dword = signal to latch it
end
// nempty_rr & nempty => shall be at least 2 elements in fifo - safe to read
// nempty_rr & nempty => shall be at least 2 elements in fifo
always @ (posedge txusrclk2)
begin
txdata_resync_nempty_r <= txdata_resync_nempty;
......@@ -182,7 +237,9 @@ if (DATA_BYTE_WIDTH == 4) begin
assign txcomwake_gtx = txcomwake_gtx_f;
assign txcominit_gtx = txcominit_gtx_f;
assign txelecidle_gtx = txelecidle_gtx_f;
*/
end
else
if (DATA_BYTE_WIDTH == 2) begin
// no resync is needed => straightforward assignments
......
......@@ -27,7 +27,7 @@ module sata_phy #(
// initial reset, resets PLL. After pll is locked, an internal sata reset is generated.
input wire extrst,
// sata clk, generated in pll as usrclk2
output wire clk, // 75KHz, bufg
output wire clk, // 75MHz, bufg
output wire rst,
// reliable clock to source drp and cpll lock det circuits
......
This diff is collapsed.
/*******************************************************************************
* Module: resync_data
* Date:2015-12-22
* Author: Andrey Filippov
* Description: Resynchronize data between clock domains. No over/underruns
* are checker, start with half FIFO full. Async reset sets
* specifies output values regardless of the clocks
*
* Copyright (c) 2014 Elphel, Inc.
* resync_data.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.
*
* resync_data.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 resync_data
#(
parameter integer DATA_WIDTH=16,
parameter integer DATA_DEPTH=4, // >= 2
parameter INITIAL_VALUE = 0
) (
input arst, // async reset, active high (global)
input srst, // same as arst, but relies on the clocks
input wclk, // write clock - positive edge
input rclk, // read clock - positive edge
input we, // write enable
input re, // read enable
input [DATA_WIDTH-1:0] data_in, // input data
output reg [DATA_WIDTH-1:0] data_out, // output data
output reg valid // data valid @ rclk
);
localparam integer DATA_2DEPTH=(1<<DATA_DEPTH)-1;
reg [DATA_WIDTH-1:0] ram [0:DATA_2DEPTH];
reg [DATA_DEPTH-1:0] raddr;
reg [DATA_DEPTH-1:0] waddr;
reg [1:0] rrst = 3;
always @ (posedge rclk or posedge arst) begin
if (arst) valid <= 0;
else if (srst) valid <= 0;
else if (&waddr[DATA_DEPTH-2:0] && we) valid <= 1; // just once set and stays until reset
end
always @ (posedge wclk or posedge arst) begin
if (arst) waddr <= 0;
else if (srst) waddr <= 0;
else if (we) waddr <= waddr + 1;
end
always @ (posedge rclk or posedge arst) begin
if (arst) rrst <= 3;
else if (srst) rrst <= 3; // resync to rclk
else rrst <= rrst << 1;
if (arst) raddr <= 0;
else if (rrst[0]) raddr <= 0;
else if (re || rrst[1]) raddr <= raddr + 1;
if (arst) data_out <= INITIAL_VALUE;
else if (rrst[0]) data_out <= INITIAL_VALUE;
else if (re || rrst[1]) data_out <= ram[raddr];
end
always @ (posedge wclk) begin
if (we) ram[waddr] <= data_in;
end
endmodule
Subproject commit 9a17dbfae721f542dc546b8659620ecdc441a9ee
Subproject commit 8af3d0c0ec45090474e57e1501e852187287fdbb
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