Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / mif.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: mif.v
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
//
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// 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; version 2 of the License.
//
// 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; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
//
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// have any questions.
//
// ========== Copyright Header End ============================================
/*%W% %G%*/
/*************************************************************************
*
* File Name : mif
* Author Name : John Lo
* Description :
* Parent Module:
* Child Module: many
* Interface Mod: many.
* Date Created : 7/24/03
*
* Copyright (c) 2008, Sun Microsystems, Inc.
* Sun Proprietary and Confidential
*
*
* Design Notes: the MDC clock is generated by
* clk divided by 2 to the power of `IDLE_CNT_SIZE.
* The IEEE spec requires the MDC clock
* to be less or equal to 400ns.
* But today's phy can support upto 12.5Mhz
* MDC clock.
* If the clk is higher than 125 mhz
* user of this IP needs to make sure
* the MDC clock can still work with
* Phy chip.
*
* When ST (Start of Frame) = 2'b01
* 1. ST (Start of Frame) = 2'b01 for original phy
* register address space per
* IEEE 802.3u Clause 22 MII specification.
* 2. ST (Start of Frame) = 2'b00 for a new
* indirect access cycle of extra register
* address space per
* IEEE 802.3ae Clause 45 MDIO specification.
*
*
* There are only two places that need to be modified
* when moving up core_clk frequency.
*
* 1. Change the following define variable to fit
* specific core_clk freq in a propotional linear scale way.
* 2. Add more digital delay for MDIO and mdo_en
* to satisfy 10ns (min) setup and hold time requirements.
* Please refer to Clause 22.3.4 for detail
*
* * mif_init_done_stat, send_init_fm, mif_init_fm
* are three key signals for the new auto init feature.
*
* * Auto inti frame function is merged with
* regular ld_frame since these two behavior are simular.
*
*
* BUG to be fixed: Must fix the poll_fm_rd_opcode bug. 1-30-06
*
*
*
***************************************************************/
`include "mif.h"
`define IDLE_CNT_SIZE 7 // 250mhz core clk
`define IDLE_CNT_TEMP1 `IDLE_CNT_SIZE'b0 // 7'b0
`define IDLE_CNT_BASE ~(`IDLE_CNT_TEMP1) // 7'b111_1111 == 7'h7F
`define IDLE_CNT_MSB `IDLE_CNT_SIZE - 1 // 6 <- MSB
`define IDLE_CNT_R `IDLE_CNT_MSB:0 // 6:0
`define TX_BIT_DN 7'b100_0000 // 7'h40 = 64 = 7'b100_0000
`define RX_BIT_DN `TX_BIT_DN - 7'd1 // 7'h3F = 63 = 7'b011_1111
`define CLAUSE22_ST 2'b01
`define CLAUSE45_ST 2'b00
module mif(
`ifdef NEPTUNE
xge_mif_error_0,
xge_mif_error_1,
peu_mif_error,
peu_mif_rdy,
spc_mif_rdy,
mif_spc_req,
mif_spc_addr,
spc_mif_ack,
spc_mif_rdata,
mif_initdone,
`else
`endif
clk,
pio_core_reset,
sel_mif, // sel
pio_rd, // r/w
pio_addr, // address
pio_wdata, // wr_data
ack_mif,
rdata_mif, // rd_data
pio_err_mif,
atca_GE,
MDINT0,
MDINT1,
PHY_MDINT0_L,
PHY_MDINT1_L,
// mdio output signals
mdclk,
mdo,
mif_pio_intr,
// mdio input signals
mdi,
mdi_0,
mdi_1,
mdi_2
);
`ifdef NEPTUNE
/* ----- serdes related --------- */
input xge_mif_error_0;
input xge_mif_error_1;
input peu_mif_error;
input peu_mif_rdy;
input spc_mif_rdy;
output mif_spc_req;
output [4:0] mif_spc_addr;
input spc_mif_ack;
input [15:0] spc_mif_rdata;
output mif_initdone;
`else
`endif
input clk;
input pio_core_reset;
input sel_mif; // sel
input pio_rd; // r/w
input [8:0] pio_addr; // address
input [31:0] pio_wdata; // wr_data
output ack_mif;
output [31:0] rdata_mif; // rd_data
output pio_err_mif;
output atca_GE;
output MDINT0;
output MDINT1;
input PHY_MDINT0_L;
input PHY_MDINT1_L;
// mdio output outputs
output mdclk;
output mdo;
output mif_pio_intr;
// mdio input signals
input mdi;
input mdi_0;
input mdi_1;
input mdi_2; // pcie serdes
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire clr_idle_timer; // From mif_exec_sm of mif_exec_sm.v
wire clr_mdo_en; // From mif_exec_sm of mif_exec_sm.v
wire clr_read_instr; // From mif_exec_sm of mif_exec_sm.v
wire mdi_en; // From mif_exec_sm of mif_exec_sm.v
wire set_mdo_en; // From mif_exec_sm of mif_exec_sm.v
wire set_read_instr; // From mif_exec_sm of mif_exec_sm.v
wire shift_en; // From mif_exec_sm of mif_exec_sm.v
wire ta_clr_mdo_en; // From mif_exec_sm of mif_exec_sm.v
// End of automatics
wire rd_op_code;
wire wr_op_code;
wire instr_pnd,wr_done,rd_done,illegal_instr,fetch_instr,
poll_instr,ld_instr,ld_output_reg,ld_poll_status,tx_bit_done,rx_bit_done,
frame_mdo,shift_out,rac_pls,
poll_en,bb_mode,bb_mdc,new_bb_mdc,new_bb_mdo,new_bb_mdo_en,
bb_mdo,bb_mdo_en,mdo_fclk,mdo_en_fclk,mdo_en,
read_instr;
wire mdclk;
wire mdo;
wire mdo_temp;
wire mdio_en;
wire wr_en;
wire fclk;
wire [4:0] port_addr;
wire [4:0] poll_dev_addr;
wire [4:0] poll_prt_addr;
wire [4:0] idle_count2;
wire [`IDLE_CNT_R]idle_count1, div_count; // loj
wire mif_init_done_stat;
wire [31:0] output_reg;
wire [31:0] new_poll_status;
wire [31:0] poll_status;
wire [31:0] instr_din;
wire [31:0] frame_dout;
wire indirect_mode;
wire [31:0] config1;
reg mdi_mux;
reg ld_mif_status;
reg ld_mif_mask;
reg rac_mif_status;
/* ------------------------------ Slave I/F -------------------------------- */
reg ld_bb_mdc;
reg ld_bb_mdo;
reg ld_bb_mdo_en;
reg ld_frame_pio; // ld frame caused by PIO
wire ld_frame;
reg ld_config;
reg ld_poll_mask;
reg rac_poll_status;
reg non_qualified_addr_err;
reg [31:0] rd_data;
wire idle_done;
wire addr_err;
wire [31:0] rdata_mif;
wire [31:0] pio_wdata;
wire [31:0] wr_data;
wire [8:0] reg_offset;
wire [1:0] int_ser_sel;
wire mdi_1;
wire mdi_0;
wire reset;
wire [5:0] ex_state;
wire [2:0] ctl_state;
wire [31:0] poll_mask;
wire [31:0] mif_state_machine;
wire int_ser0;
wire int_ser1;
wire int_ser2;
wire spc_rdy;
wire spc_req;
wire spc_ack;
// vlint flag_net_has_no_load off
// vlint flag_dangling_net_within_module off
wire [31:0] shift_dout;
wire core_sel_trail;
wire frame_mdo_en;
wire manual_mode;
wire mif_initdone;
// vlint flag_dangling_net_within_module on
// vlint flag_net_has_no_load on
wire [31:0] mif_status;
wire [31:0] mif_mask;
wire mif_interrupt;
wire [1:0] st;
wire [31:0] poll_fm;
wire [31:0] mif_init_fm;
wire send_init_fm;
wire send_init_fm_pls;
wire [3:0] mif_init_state;
wire rd_wr,core_sel,core_sel_lead,shift_in,reset_pls,fclk_pls,
d1_mdo_en_fclk,d2_mdo_en_fclk,d3_mdo_en_fclk,
d1_mdo_fclk,d2_mdo_fclk,d3_mdo_fclk;
assign mif_state_machine = {3'h0,
spc_rdy,
spc_req,
spc_ack,
send_init_fm,
mif_init_state[3:0],
port_addr[4:0],
mdi_2,mdi_1,mdi_0,
mdclk,mdo_en,mdo,mdi,
ctl_state[2:0],ex_state[5:0]};
/* ------------------------------------------------------------------------- */
//***** Register the mif interface signals *********************
// To reduce gate count -> take register away
// If there is a timing problem, register them again here.
//**************************************************************
FD1 core_reset_FD1 (.D(pio_core_reset),.CP(clk),.Q(reset));
FD1 rd_wr_FD1 (.D(pio_rd), .CP(clk),.Q(rd_wr));
FD1 core_sel_FD1 (.D(sel_mif), .CP(clk),.Q(core_sel));
// the following reset_pls guarantees the MDC clock being funcitonal
// in the reset state.
pls_gen pls_gen(.clk(clk),.in(reset),.out(reset_pls));
RegDff #(9) reg_offset_RegDff(.din(pio_addr[8:0]),
.clk(clk),
.qout(reg_offset[8:0]));
RegDff #(32) wr_data_RegDff (.din(pio_wdata[31:0]),
.clk(clk),
.qout(wr_data[31:0]));
PlsGen2 core_sel_PlsGen2(.sig_in(core_sel),.clk(clk),
.lead(core_sel_lead),
.trail(core_sel_trail));
wire rac_ok = core_sel_lead & rd_wr;
assign wr_en = core_sel_lead & (~rd_wr);
RegDff #(32) rdata_mif_RegDff (.din(rd_data),.clk(clk),
.qout(rdata_mif[31:0]));
FD1 ack_mif_FD1 (.D(core_sel_lead),.CP(clk),.Q(ack_mif));
FD1 rac_pls_FD1 (.D(rac_ok),.CP(clk),.Q(rac_pls));
assign addr_err = non_qualified_addr_err & core_sel_lead;
FD1 pio_err_mif_FD1 (.D(addr_err),.CP(clk),.Q(pio_err_mif));
always @ (/*AUTOSENSE*/bb_mdc or bb_mdo or bb_mdo_en or config1
or frame_dout or mif_init_fm or mif_mask
or mif_state_machine or mif_status or output_reg or poll_fm
or poll_mask or poll_status or rac_pls or reg_offset
or wr_en)
begin
non_qualified_addr_err = 0;
rd_data = 32'hDEADBEEF;
ld_bb_mdc = 0;
ld_bb_mdo = 0;
ld_bb_mdo_en = 0;
ld_frame_pio = 0;
ld_config = 0;
ld_poll_mask = 0;
rac_poll_status = 0;
ld_mif_status = 0;
ld_mif_mask = 0;
rac_mif_status = 0;
case (reg_offset[8:0]) // synopsys parallel_case full_case infer_mux
// mif addr range is from 1_0000_0000 to 1_1111_1111 (9'h100 to 9'h1FF)
9'h000: begin
ld_bb_mdc = wr_en;
rd_data = {31'h0,bb_mdc};
end
9'h001: begin
ld_bb_mdo = wr_en;
rd_data = {31'h0,bb_mdo};
end
9'h002: begin
ld_bb_mdo_en = wr_en;
rd_data = {31'h0,bb_mdo_en};
end
9'h003: begin
ld_frame_pio = wr_en;
rd_data = output_reg;
end
9'h004: begin
ld_config = wr_en;
rd_data = config1;
end
9'h005: begin
rac_poll_status = rac_pls;
rd_data = poll_status;
end
9'h006: begin
ld_poll_mask = wr_en;
rd_data = poll_mask;
end
9'h007: begin
rd_data = mif_state_machine;
end
9'h008: begin
ld_mif_status = wr_en;
rd_data = mif_status;
end
9'h009: begin
ld_mif_mask = wr_en;
rd_data = mif_mask;
end
9'h00A: begin
rd_data = mif_init_fm;
end
9'h00B: begin
rd_data = frame_dout;
end
9'h00C: begin
rd_data = poll_fm;
end
default:begin
rd_data = 32'hdead_beef;
non_qualified_addr_err = 1;
end
endcase
end // always @ (...
/////////////////////////////////////////////////////////////////
// register instantiation
/////////////////////////////////////////////////////////////////
/* ---------------------------- Bit-Bang I/F ------------------------------- */
assign new_bb_mdc = reset ? 1'b0 :
(ld_bb_mdc ? wr_data[0] : bb_mdc);
assign new_bb_mdo = reset ? 1'b0 :
(ld_bb_mdo ? wr_data[0] : bb_mdo);
assign new_bb_mdo_en = reset ? 1'b0 :
(ld_bb_mdo_en ? wr_data[0] : bb_mdo_en);
FD1 BB_MDC_FF(.D(new_bb_mdc),.CP(clk),.Q(bb_mdc));
FD1 BB_MDO_FF(.D(new_bb_mdo),.CP(clk),.Q(bb_mdo));
FD1 BB_MDO_EN_FF(.D(new_bb_mdo_en),.CP(clk),.Q(bb_mdo_en));
/* ------------------------------------------------------------------------- */
/* ---------------------------- Frame Register ----------------------------- */
assign ld_frame = ld_frame_pio | send_init_fm_pls;
wire [31:0] frame_din = send_init_fm ? mif_init_fm : wr_data;
xREG #(32) FRAME_REG_xREG(.clk(clk),.reset(reset),.en(ld_frame),.din(frame_din),.qout(frame_dout));
/* ------------------------------------------------------------------------- */
/* ------------------------- Output Register ------------------------------- */
xREG #(16) output16b_xREG(.clk(clk),.reset(reset),.en(ld_output_reg),.din(shift_dout[15:0]),.qout(output_reg[15:0]));
// When polling for completion: output_reg[16] serves as a "execution done".
// When this bit is set to'1', the instruction execution has been completed.
reg output_reg_b16;
always @ (posedge clk)
if (reset)
output_reg_b16 <= 1'b0;
else if (ld_frame)
output_reg_b16 <= 1'b0;
else if (ld_output_reg)
output_reg_b16 <= 1'b1;
else
output_reg_b16 <= output_reg_b16;
assign output_reg[16] = output_reg_b16;
assign output_reg[31:17] = 0;
/* ------------------------------------------------------------------------- */
/* ------------------------ Configuration Register ------------------------- */
xREG2 #(20) config1_xREG2(.clk(clk),
.reset(reset),
.reset_value({20'b0000_1000_0000_0000_0000}),
.load(ld_config),
.din(wr_data[19:0]),
.qout(config1[19:0]));
assign manual_mode = config1[0];
assign int_ser_sel = config1[2:1];
assign poll_en = config1[3];
assign bb_mode = config1[4];
assign poll_dev_addr = config1[9:5];
assign poll_prt_addr = config1[14:10];
assign indirect_mode = config1[15];
assign atca_GE = config1[16]; // por = 0
// status
assign config1[31:20] = 0;
/* ------------------------------------------------------------------------- */
/* ----------------------- Poll Mask Register ------------------------------ */
xREG2 #(16) poll_mask_xREG2(.clk(clk),.reset(reset),.reset_value(16'hFFFF),
.load(ld_poll_mask),.din(wr_data[15:0]),.qout(poll_mask[15:0]));
assign poll_mask[31:16] = 0;
/* ------------------------------------------------------------------------- */
/* --------------------------- Status Register ----------------------------- */
assign new_poll_status[31:16] = reset ? 16'h0 :
(ld_poll_status ? shift_dout[15:0] : poll_status[31:16]);
assign new_poll_status[0] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[16] ^ shift_dout[0]) : (rac_poll_status ? 1'b0 : poll_status[0]));
assign new_poll_status[1] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[17] ^ shift_dout[1]) : (rac_poll_status ? 1'b0 : poll_status[1]));
assign new_poll_status[2] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[18] ^ shift_dout[2]) : (rac_poll_status ? 1'b0 : poll_status[2]));
assign new_poll_status[3] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[19] ^ shift_dout[3]) : (rac_poll_status ? 1'b0 : poll_status[3]));
assign new_poll_status[4] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[20] ^ shift_dout[4]) : (rac_poll_status ? 1'b0 : poll_status[4]));
assign new_poll_status[5] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[21] ^ shift_dout[5]) : (rac_poll_status ? 1'b0 : poll_status[5]));
assign new_poll_status[6] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[22] ^ shift_dout[6]) : (rac_poll_status ? 1'b0 : poll_status[6]));
assign new_poll_status[7] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[23] ^ shift_dout[7]) : (rac_poll_status ? 1'b0 : poll_status[7]));
assign new_poll_status[8] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[24] ^ shift_dout[8]) : (rac_poll_status ? 1'b0 : poll_status[8]));
assign new_poll_status[9] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[25] ^ shift_dout[9]) : (rac_poll_status ? 1'b0 : poll_status[9]));
assign new_poll_status[10] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[26] ^ shift_dout[10]) : (rac_poll_status ? 1'b0 : poll_status[10]));
assign new_poll_status[11] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[27] ^ shift_dout[11]) : (rac_poll_status ? 1'b0 : poll_status[11]));
assign new_poll_status[12] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[28] ^ shift_dout[12]) : (rac_poll_status ? 1'b0 : poll_status[12]));
assign new_poll_status[13] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[29] ^ shift_dout[13]) : (rac_poll_status ? 1'b0 : poll_status[13]));
assign new_poll_status[14] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[30] ^ shift_dout[14]) : (rac_poll_status ? 1'b0 : poll_status[14]));
assign new_poll_status[15] = reset ? 1'b0 : (ld_poll_status ?
(poll_status[31] ^ shift_dout[15]) : (rac_poll_status ? 1'b0 : poll_status[15]));
RegDff #(32) STATUS_RegDff(.clk(clk),.din(new_poll_status),.qout(poll_status));
/* ------------------------------------------------------------------------- */
/* ------------------------------ Interrupts ------------------------------- */
wire poll_interrupt = |(poll_status[15:0] & (~poll_mask[15:0]));
reg mif_pio_intr;
always @ (posedge clk)
mif_pio_intr <= poll_interrupt | mif_interrupt;
/* ------------------------------------------------------------------------- */
/* ---------- common serdes status and mask register ----------- */
wire mac_err0_pls;
wire mac_err1_pls;
wire peu_err_pls;
wire sync_MDINT0_L;
wire sync_MDINT1_L;
wire MDINT0;
wire MDINT1;
wire PHY_MDINT0_L;
wire PHY_MDINT1_L;
`ifdef NEPTUNE
wire xge_err0;
wire xge_err1;
wire peu_err;
SYNC_CELL xge_err0_SYNC_CELL(.D(xge_mif_error_0),.CP(clk),.Q(xge_err0));
SYNC_CELL xge_err1_SYNC_CELL(.D(xge_mif_error_1),.CP(clk),.Q(xge_err1));
SYNC_CELL peu_err_SYNC_CELL(.D(peu_mif_error), .CP(clk),.Q(peu_err));
pls_gen mac_err0_pls_gen (.clk(clk),.in(xge_err0),.out(mac_err0_pls));
pls_gen mac_err1_pls_gen (.clk(clk),.in(xge_err1),.out(mac_err1_pls));
pls_gen peu_err_pls_gen (.clk(clk),.in(peu_err), .out(peu_err_pls));
assign mif_status[4] = ~sync_MDINT0_L;
assign mif_status[5] = ~sync_MDINT1_L;
assign MDINT0 = mif_status[4];
assign MDINT1 = mif_status[5];
`else // !ifdef NEPTUNE
assign mac_err0_pls = 1'b0;
assign mac_err1_pls = 1'b0;
assign peu_err_pls = 1'b0;
assign mif_status[4] = 1'b0; // cc 081106
assign mif_status[5] = 1'b0; // cc 081106
assign MDINT0 = ~sync_MDINT0_L; // cc 081106
assign MDINT1 = ~sync_MDINT1_L; // cc 081106
`endif // !ifdef NEPTUNE
// eco @ 7-25-06
SYNC_CELL sync_MDION0_L_SYNC_CELL(.D(PHY_MDINT0_L),.CP(clk),.Q(sync_MDINT0_L));
SYNC_CELL sync_MDION1_L_SYNC_CELL(.D(PHY_MDINT1_L),.CP(clk),.Q(sync_MDINT1_L));
assign mif_status[0] = mif_init_done_stat;
FD1 mif_initdone_FD1 (.D(mif_init_done_stat),.CP(clk),.Q(mif_initdone));
RAC_FF stat0_RAC_FF(.clk(clk),.reset(reset),.set(mac_err0_pls),.rst(rac_mif_status),.load(ld_mif_status),.load_data(wr_data[1]),.dout(mif_status[1]));
RAC_FF stat1_RAC_FF(.clk(clk),.reset(reset),.set(mac_err1_pls),.rst(rac_mif_status),.load(ld_mif_status),.load_data(wr_data[2]),.dout(mif_status[2]));
RAC_FF stat2_RAC_FF(.clk(clk),.reset(reset),.set(peu_err_pls), .rst(rac_mif_status),.load(ld_mif_status),.load_data(wr_data[3]),.dout(mif_status[3]));
// assign mif_status[4] = ~sync_MDINT0_L; // cc 081106
// assign mif_status[5] = ~sync_MDINT1_L; // cc 081106
assign mif_status[31:6] = 0;
assign mif_mask[31:6] = 0;
// assign MDINT0 = mif_status[4]; // cc 081106
// assign MDINT1 = mif_status[5]; // cc 081106
assign mif_interrupt = (mif_status[0] & (~mif_mask[0])) |
(mif_status[1] & (~mif_mask[1])) |
(mif_status[2] & (~mif_mask[2])) |
(mif_status[3] & (~mif_mask[3])) |
(mif_status[4] & (~mif_mask[4])) |
(mif_status[5] & (~mif_mask[5])) ;
xREG2 #(6) mif_mask_xREG2 (
.clk(clk),
.reset(reset),
.reset_value({6{1'b1}}),
.load(ld_mif_mask),
.din(wr_data[5:0]),
.qout(mif_mask[5:0]));
// cc081106
// assign mif_interrupt = (mif_status[0] & (~mif_mask[0])) |
// (mif_status[1] & (~mif_mask[1])) |
// (mif_status[2] & (~mif_mask[2])) |
// (mif_status[3] & (~mif_mask[3])) |
// (mif_status[4] & (~mif_mask[4])) |
// (mif_status[5] & (~mif_mask[5])) ;
/* ------------------------------------------------------------------------- */
/* ------------------------- Frame Mode Engine ----------------------------- */
mif_control_sm mif_control_sm
(/*AUTOINST*/
// Outputs
.fetch_instr (fetch_instr),
.poll_instr (poll_instr),
.ld_output_reg (ld_output_reg),
.ld_poll_status (ld_poll_status),
.ctl_state (ctl_state[2:0]),
// Inputs
.clk (clk),
.reset (reset),
.instr_pnd (instr_pnd),
.poll_en (poll_en),
.mif_pio_intr (mif_pio_intr),
.wr_done (wr_done),
.rd_done (rd_done),
.illegal_instr (illegal_instr));
mif_exec_sm mif_exec_sm
(/*AUTOINST*/
// Outputs
.illegal_instr (illegal_instr),
.set_read_instr (set_read_instr),
.clr_read_instr (clr_read_instr),
.set_mdo_en (set_mdo_en),
.clr_mdo_en (clr_mdo_en),
.ta_clr_mdo_en (ta_clr_mdo_en),
.mdi_en (mdi_en),
.shift_en (shift_en),
.clr_idle_timer (clr_idle_timer),
.wr_done (wr_done),
.rd_done (rd_done),
.ex_state (ex_state[5:0]),
// Inputs
.clk (clk),
.reset (reset),
.ld_instr (ld_instr),
.rd_op_code (rd_op_code),
.wr_op_code (wr_op_code),
.read_instr (read_instr),
.idle_done (idle_done),
.tx_bit_done (tx_bit_done),
.rx_bit_done (rx_bit_done));
// bit_shifter_en_ld_X32 SHIFTER(clk,ld_instr,shift_en,shift_in,instr_din,
// shift_out,shift_dout);
bit_shifter_en_ld_X32 SHIFTER(
.reset(reset),
.clk(clk),
.ld_en(ld_instr),
.shift_en(shift_en),
.shift_in(shift_in),
.din(instr_din),
.shift_out(shift_out),
.dout(shift_dout));
assign shift_in = mdi_en ? mdi_mux : shift_out;
// rd_op_code and wr_op_code are used by mif_exec_sm to see which action to take.
//
// Clause 22 MDIO (ST=2'b01) Clause 45 MDIO (ST=2'b00)
// | |
// V V
assign rd_op_code = (shift_dout[31:28] == {`CLAUSE22_ST,2'b10}) | (shift_dout[31:29] == {`CLAUSE45_ST,1'b1});
assign wr_op_code = (shift_dout[31:28] == {`CLAUSE22_ST,2'b01}) | (shift_dout[31:29] == {`CLAUSE45_ST,1'b0});
RS_FF read_instr_RS_FF(
.set(set_read_instr),
.rst(clr_read_instr),
.clk(clk),
.reset(reset),
.qout(read_instr));
RS_FF RS_FF(
.set(set_mdo_en),
.rst(clr_mdo_en | ta_clr_mdo_en),
.clk(clk),
.reset(reset),
.qout(mdo_en));
// IDLE counter
Counter #(`IDLE_CNT_SIZE) idle_count1_Counter (.reset(reset_pls | clr_idle_timer), // loj
.clk(clk),
.ce(!idle_done),
.count(idle_count1));
wire idle_count_en = !idle_done & (idle_count1 == `IDLE_CNT_BASE);
counter_X5 IDLE_CNT2 (.clk(clk), // loj, count 32 bit time for idle period.
.clr(reset_pls | clr_idle_timer),
.enable(idle_count_en), // loj
.count(idle_count2)
);
RS_FF idle_done_RS_FF(
.set(idle_count_en & (idle_count2 == 5'h1F)),
.rst(clr_idle_timer),
.clk(clk),
.reset(reset),
.qout(idle_done));
// free running counter. core_clk/(2 to the power of `IDLE_CNT_SIZE)
Counter #(`IDLE_CNT_SIZE) div_count_Counter (.reset(reset_pls), // loj
.clk(clk),
.ce(1'b1),
.count(div_count));
assign fclk = div_count[`IDLE_CNT_MSB];
RS_FF instr_pnd_RS_FF(.set(ld_frame),.rst(ld_output_reg),.clk(clk),
.reset(reset),.qout(instr_pnd));
assign tx_bit_done = (div_count == `TX_BIT_DN); // loj 6'h20-> 7'h40; 7'b100_0000
assign rx_bit_done = (div_count == `RX_BIT_DN); // loj 6'h1E-> 7'h3E;
assign ld_instr = fetch_instr | poll_instr;
assign st = indirect_mode ? `CLAUSE45_ST : `CLAUSE22_ST;
assign poll_fm = {st,2'b10,poll_prt_addr,poll_dev_addr,2'b10,16'h0};
assign instr_din = poll_instr ? poll_fm[31:0] :
frame_dout[31:0];
PlsGen fclk_pls_PlsGen (.reset(reset),.clk(clk),.iSigIn(fclk),.oPlsOut(fclk_pls));
xREG #(5) port_addr_xREG(.clk(clk),.reset(reset),.en(ld_instr),.din(instr_din[27:23]),.qout(port_addr[4:0]));
//*************************************************************************
// To meet minimum hold time 10ns, this piece of logic should be changed
// for system clock other than 300Mhz. - loj
//*************************************************************************
// mdo_en
xREG #(1) mdo_en_fclk_xREG(.din(mdo_en), // mdo_en is used as internal signal.
.clk(clk),
.en(fclk_pls),
.reset(reset | ta_clr_mdo_en),
.qout(mdo_en_fclk)); // create 1 core_clk delay
FD1 FRAME_MDO_EN_d1(.D(mdo_en_fclk), .CP(clk),.Q(d1_mdo_en_fclk));// create 1 core_clk delay
FD1 FRAME_MDO_EN_d2(.D(d1_mdo_en_fclk),.CP(clk),.Q(d2_mdo_en_fclk));// create 1 core_clk delay
FD1 FRAME_MDO_EN_d3(.D(d2_mdo_en_fclk),.CP(clk),.Q(d3_mdo_en_fclk));// create 1 core_clk delay
FD1 FRAME_MDO_EN_d4(.D(d3_mdo_en_fclk),.CP(clk),.Q(frame_mdo_en)); // create 1 core_clk delay
// mdo
xREG #(1) mdo_fclk_xREG(.din(!idle_done | shift_out),
.clk(clk),
.en(fclk_pls),
.reset(reset),
.qout(mdo_fclk)); // create 1 core_clk delay
FD1 FRAME_MDO_FF_d1(.D(mdo_fclk), .CP(clk),.Q(d1_mdo_fclk)); // create 1 core_clk delay
FD1 FRAME_MDO_FF_d2(.D(d1_mdo_fclk),.CP(clk),.Q(d2_mdo_fclk)); // create 1 core_clk delay
FD1 FRAME_MDO_FF_d3(.D(d2_mdo_fclk),.CP(clk),.Q(d3_mdo_fclk)); // create 1 core_clk delay
FD1 FRAME_MDO_FF_d4(.D(d3_mdo_fclk),.CP(clk),.Q(frame_mdo)); // create 1 core_clk delay
/* ------------------------------------------------------------------------- */
/* -------------------------------- MIF ------------------------------------ */
// Do not disable mdclk when niu_reset_l is active. Hedwig needs it to clock
// in synchronous reset.
assign mdclk = bb_mode ? bb_mdc : fclk;
assign mdo_temp= bb_mode ? bb_mdo : frame_mdo; // loj 1-27-06 // unqualified mdo
assign mdio_en = bb_mode ? bb_mdo_en : frame_mdo_en; // loj 1-24-06
assign mdo = mdo_temp | (~mdio_en); // loj 1-27-06
assign int_ser0 = int_ser_sel[1:0] == 2'b00;
assign int_ser1 = int_ser_sel[1:0] == 2'b01;
assign int_ser2 = int_ser_sel[1:0] == 2'b10;
always @ (bb_mode or int_ser0 or int_ser1 or int_ser2 or mdi
or mdi_0 or mdi_1 or mdi_2 or port_addr)
begin
if (bb_mode)
mdi_mux = int_ser0 ? mdi_0 :
int_ser1 ? mdi_1 :
int_ser2 ? mdi_2 :
mdi;
else // frame_mode
mdi_mux = (port_addr == `PORT_ADDR_0) ? mdi_0 :
(port_addr == `PORT_ADDR_1) ? mdi_1 :
(port_addr == `PORT_ADDR_2) ? mdi_2 :
mdi;
end
/* ------------------------------------------------------------------------- */
`ifdef NEPTUNE
mif_init_ctl mif_init_ctl
(
// Outputs
.mif_spc_req (mif_spc_req),
.mif_spc_addr (mif_spc_addr[4:0]),
.mif_init_done_stat (mif_init_done_stat),
.mif_init_state (mif_init_state[3:0]),
.send_init_fm (send_init_fm),
.send_init_fm_pls (send_init_fm_pls),
.mif_init_fm (mif_init_fm[31:0]),
.spc_rdy (spc_rdy),
.spc_req (spc_req),
.spc_ack (spc_ack),
// Inputs
.clk (clk),
.reset (reset),
.st (st[1:0]),
.peu_mif_rdy (peu_mif_rdy),
.spc_mif_rdy (spc_mif_rdy),
.spc_mif_ack (spc_mif_ack),
.spc_mif_rdata (spc_mif_rdata[15:0]),
.ld_output_reg (ld_output_reg));
`else // N2
assign mif_init_done_stat = 1'b1;
assign mif_init_state = 4'b0;
assign send_init_fm = 1'b0;
assign send_init_fm_pls = 1'b0;
assign mif_init_fm =32'b0;
assign spc_rdy = 1'b1;
assign spc_req = 1'b0;
assign spc_ack = 1'b0;
`endif // !ifdef NEPTUNE
/* --------------- spare gates --------------- */
`ifdef NEPTUNE
wire [3:0] do_nad;
wire [3:0] do_nor;
wire [3:0] do_inv;
wire [3:0] do_mux;
wire [3:0] do_q;
wire so;
mac_spare_gates mac_mif_spare_gates (
.di_nd3 ({1'h1, 1'h1, do_q[3]}),
.di_nd2 ({1'h1, 1'h1, do_q[2]}),
.di_nd1 ({1'h1, 1'h1, do_q[1]}),
.di_nd0 ({1'h1, 1'h1, do_q[0]}),
.di_nr3 ({1'h0, 1'h0}),
.di_nr2 ({1'h0, 1'h0}),
.di_nr1 ({1'h0, 1'h0}),
.di_nr0 ({1'h0, 1'h0}),
.di_inv (do_nad[3:0]),
.di_mx3 ({1'h0, 1'h0}),
.di_mx2 ({1'h0, 1'h0}),
.di_mx1 ({1'h0, 1'h0}),
.di_mx0 ({1'h0, 1'h0}),
.mx_sel (do_nor[3:0]),
.di_reg (do_inv[3:0]),
.wt_ena (do_mux[3:0]),
.rst ({4{reset}}),
.si (1'h0),
.se (1'h0),
.clk (clk),
.do_nad (do_nad[3:0]),
.do_nor (do_nor[3:0]),
.do_inv (do_inv[3:0]),
.do_mux (do_mux[3:0]),
.do_q (do_q[3:0]),
.so (so)
);
`else
`endif
endmodule // mif