1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-17 20:02:53 +08:00
oh/elink/hdl/etx_cfg.v
Andreas Olofsson d275406aa6 Reset timing optimization
- holding rx in reset state until tx is done
- removing reset from all pipeline registers
- removing reset from oddr/iddr
- the idea is to keep things quiet not to block in lots of places. The only real block needed is in the FIFO to keep "noise" from propagating past the link. The link should be kept in a safe reset state until the rx fram is stable and the clock is running so that the pipe can be cleaned out.
2015-10-08 10:34:59 -04:00

162 lines
5.5 KiB
Verilog

/*
########################################################################
ELINK TX CONFIGURATION REGISTER FILE
########################################################################
*/
`include "elink_regmap.v"
module etx_cfg (/*AUTOARG*/
// Outputs
mi_dout, tx_enable, mmu_enable, gpio_enable, remap_enable,
gpio_data, ctrlmode, ctrlmode_bypass,
// Inputs
reset, clk, mi_en, mi_we, mi_addr, mi_din, tx_status
);
/******************************/
/*Compile Time Parameters */
/******************************/
parameter PW = 104;
parameter RFAW = 6;
parameter DEFAULT_VERSION = 16'h0000;
/******************************/
/*HARDWARE RESET (EXTERNAL) */
/******************************/
input reset;
input clk;
/*****************************/
/*SIMPLE MEMORY INTERFACE */
/*****************************/
input mi_en;
input mi_we;
input [RFAW+1:0] mi_addr; // complete address (no shifting!)
input [31:0] mi_din; // (lower 2 bits not used)
output [31:0] mi_dout;
/*****************************/
/*ELINK CONTROL SIGNALS */
/*****************************/
//tx (static configs)
output tx_enable; // enable signal for TX
output mmu_enable; // enables MMU on transmit path
output gpio_enable; // forces TX output pins to constants
output remap_enable; // enable address remapping
input [15:0] tx_status; // etx status signals
//sampled by tx_lclk (test)
output [8:0] gpio_data; // data for elink outputs (static)
//dynamic (control timing by use mode)
output [3:0] ctrlmode; // value for emesh ctrlmode tag
output ctrlmode_bypass; // selects ctrlmode
//registers
reg [15:0] ecfg_version_reg;
reg [10:0] ecfg_tx_config_reg;
reg [8:0] ecfg_tx_gpio_reg;
reg [2:0] ecfg_tx_status_reg;
reg [31:0] mi_dout;
reg ecfg_access;
//wires
wire ecfg_read;
wire ecfg_write;
wire ecfg_tx_config_write;
wire ecfg_tx_gpio_write;
wire ecfg_tx_test_write;
wire ecfg_tx_addr_write;
wire ecfg_tx_data_write;
wire loop_mode;
/*****************************/
/*ADDRESS DECODE LOGIC */
/*****************************/
//read/write decode
assign ecfg_write = mi_en & mi_we;
assign ecfg_read = mi_en & ~mi_we;
//Config write enables
assign ecfg_version_write = ecfg_write & (mi_addr[RFAW+1:2]==`E_VERSION);
assign ecfg_tx_config_write = ecfg_write & (mi_addr[RFAW+1:2]==`ETX_CFG);
assign ecfg_tx_status_write = ecfg_write & (mi_addr[RFAW+1:2]==`ETX_STATUS);
assign ecfg_tx_gpio_write = ecfg_write & (mi_addr[RFAW+1:2]==`ETX_GPIO);
//###########################
//# TX CONFIG
//###########################
always @ (posedge clk)
if(reset)
ecfg_tx_config_reg[10:0] <= 11'b0;
else if (ecfg_tx_config_write)
ecfg_tx_config_reg[10:0] <= mi_din[10:0];
assign tx_enable = 1'b1;//TODO: fix! ecfg_tx_config_reg[0];
assign mmu_enable = ecfg_tx_config_reg[1];
assign remap_enable = ecfg_tx_config_reg[3:2]==2'b01;
assign ctrlmode[3:0] = ecfg_tx_config_reg[7:4];
assign ctrlmode_bypass = ecfg_tx_config_reg[8];
assign gpio_enable = (ecfg_tx_config_reg[10:9]==2'b01);
//###########################
//# STATUS REGISTER
//###########################
always @ (posedge clk)
if(reset)
ecfg_tx_status_reg[2:0] <= 'd0;
else
ecfg_tx_status_reg[2:0]<= ecfg_tx_status_reg[2:0] | tx_status[2:0];
//###########################
//# GPIO DATA
//###########################
always @ (posedge clk)
if (ecfg_tx_gpio_write)
ecfg_tx_gpio_reg[8:0] <= mi_din[8:0];
assign gpio_data[8:0] = ecfg_tx_gpio_reg[8:0];
//###########################
//# VERSION
//###########################
always @ (posedge clk)
if(reset)
ecfg_version_reg[15:0] <= DEFAULT_VERSION;
else if (ecfg_version_write)
ecfg_version_reg[15:0] <= mi_din[15:0];
//###############################
//# DATA READBACK MUX
//###############################
//Pipelineing readback
always @ (posedge clk)
if(ecfg_read)
case(mi_addr[RFAW+1:2])
`ETX_CFG: mi_dout[31:0] <= {21'b0, ecfg_tx_config_reg[10:0]};
`ETX_GPIO: mi_dout[31:0] <= {23'b0, ecfg_tx_gpio_reg[8:0]};
`ETX_STATUS: mi_dout[31:0] <= {16'b0, tx_status[15:3],ecfg_tx_status_reg[2:0]};
`E_VERSION: mi_dout[31:0] <= {16'b0, ecfg_version_reg[15:0]};
default: mi_dout[31:0] <= 32'd0;
endcase // case (mi_addr[RFAW+1:2])
else
mi_dout[31:0] <= 32'd0;
endmodule // ecfg_tx
/*
Copyright (C) 2015 Adapteva, Inc.
Contributed by Andreas Olofsson <andreas@adapteva.com>
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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.This program 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 (see the file
COPYING). If not, see <http://www.gnu.org/licenses/>.
*/