// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: sio_olc_ctl.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
// ========== Copyright Header End ============================================
`define SIO_L2SIO_J_BIT 31
`define SIO_L2SIO_CTGECC_MSB_BIT 30
`define SIO_L2SIO_CTGECC_LSB_BIT 25
`define SIO_L2SIO_RASUE_BIT 24
`define SIO_L2SIO_O_BIT 23
`define SIO_L2SIO_P_BIT 22
`define SIO_L2SIO_E_BIT 21
`define SIO_L2SIO_S_BIT 20
`define SIO_L2SIO_CBA2_BIT 19
`define SIO_L2SIO_CBA1_BIT 18
`define SIO_L2SIO_CBA0_BIT 17
`define SIO_L2SIO_R_BIT 16
`define RF_RDEN_OFFSTATE 1'b1
/* 2 per L2 bank, or 16 instances in SIO */
/* Write fast, Read fast */
`define SIO_OLD_RF_DATAWIDTH 32
`define SIO_OLD_RF_ADDRWIDTH 5
`define SIO_OLD_RF_DEPTH 32
/* 2 per IO device, or 4 instances in SIO */
/* Write fast, Read slow */
/* only using 68 out of 72 bits now */
`define SIO_OPD_DATA_RF_DATAWIDTH 72
`define SIO_OPD_DATA_RF_ADDRWIDTH 6
`define SIO_OPD_DATA_RF_DEPTH 64
/* 1 per IO device, or 2 instances in SIO */
/* Write fast, Read slow */
/* Logically use 18 bits wide and 16 entries */
/* Memory compiled sync fifo - with input flops, without output flops */
`define SIO_OPD_HDR_RF_DATAWIDTH 18
`define SIO_OPD_HDR_RF_ADDRWIDTH 4
`define SIO_OPD_HDR_RF_DEPTH 16
wire ojc_old_jtagsr_en_l;
wire ojc_old_jtagsr_en_r;
wire spare0_buf_32x_unused;
wire spare0_nand3_8x_unused;
wire spare0_inv_8x_unused;
wire spare0_aoi22_4x_unused;
wire spare0_buf_8x_unused;
wire spare0_oai22_4x_unused;
wire spare0_inv_16x_unused;
wire spare0_nand2_16x_unused;
wire spare0_nor3_4x_unused;
wire spare0_nand2_8x_unused;
wire spare0_buf_16x_unused;
wire spare0_nor2_16x_unused;
wire spare0_inv_32x_unused;
wire ff_ojc_cycle_sox_scanin;
wire ff_ojc_cycle_sox_scanout;
wire ff_ojc_ack_sox_scanin;
wire ff_ojc_ack_sox_scanout;
wire ff_ojc_shcnt_scanin;
wire ff_ojc_shcnt_scanout;
wire [15:0] olc_cycle_sol;
wire olc_oldue_pass_late_ue_l;
wire olc_oldue_pass_late_ue_r;
wire ff_pass_late_ue_scanin;
wire ff_pass_late_ue_scanout;
wire ff_l2b_sio_ue_err_scanin;
wire ff_l2b_sio_ue_err_scanout;
wire [15:0] olc_nextcycleis_sol;
wire ff_olc_cycle_scanin;
wire ff_olc_cycle_scanout;
wire olc_nextcycleis_soh1;
wire [2:0] hq_wr_ptr_next;
wire [2:0] hq_wr_ptr_plus1;
wire ff_hq_wr_ptr_scanin;
wire ff_hq_wr_ptr_scanout;
wire [6:0] pq_wr_ptr_next;
wire [6:0] pq_wr_ptr_plus1;
wire ff_pq_wr_ptr_scanin;
wire ff_pq_wr_ptr_scanout;
wire ff_pq_wr_en_scanout;
wire [2:0] ue_wr_ptr_next;
wire [2:0] ue_wr_ptr_plus1;
wire ff_ue_wr_ptr_scanin;
wire ff_ue_wr_ptr_scanout;
wire olc_nextcycleis_slpr;
wire header_access_same_entry;
wire header_will_access_same_entry;
wire future_payload_ready;
wire header_now_access_same_entry;
wire future_payload_was_ready;
wire olc_nextcycleis_slph;
wire ff_slp_cycle_scanin;
wire ff_slp_cycle_scanout;
wire [2:0] hq_rd_ptr_plus1;
wire ff_header_now_access_same_entry_scanin;
wire ff_header_now_access_same_entry_scanout;
wire payload_access_same_line;
wire same_line_write_above_threshold;
wire payload_will_access_same_line;
wire [6:0] pq_rd_ptr_plus1;
wire [6:0] pq_rd_ptr_plus6;
wire ff_payload_readys_scanin;
wire ff_payload_readys_scanout;
wire [2:0] hq_rd_ptr_next;
wire ff_ue_rd_ptr_inc_scanin;
wire ff_ue_rd_ptr_inc_scanout;
wire ff_hq_rd_ptr_scanin;
wire ff_hq_rd_ptr_scanout;
wire [6:0] pq_rd_ptr_next;
wire [2:0] ue_rd_ptr_next;
wire [2:0] ue_rd_ptr_plus1;
wire ff_pq_rd_ptr_scanin;
wire ff_pq_rd_ptr_scanout;
wire ff_pq_rd_en_scanout;
wire ff_ue_rd_ptr_scanin;
wire ff_ue_rd_ptr_scanout;
wire ff_l2sio_r_bit0_scanin;
wire ff_l2sio_r_bit0_scanout;
wire ff_l2sio_r_bit1_scanin;
wire ff_l2sio_r_bit1_scanout;
wire ff_l2sio_r_bit2_scanin;
wire ff_l2sio_r_bit2_scanout;
wire ff_l2sio_r_bit3_scanin;
wire ff_l2sio_r_bit3_scanout;
wire ff_l2sio_r_bit_scanin;
wire ff_l2sio_r_bit_scanout;
output olc_oldue_check_clrerr; // start of parity checking -- clear out any prior error state
output olc_oldue_check_en; // flop-enable for the parity error accumulator
output [3:0] olc_oldue_wr_en; // write enable for UE fifo
output [1:0] olc_oldue_rd_addr; // read pointer for UE fifo
output olc_oldue_selfwd; // cut-thru case --- ue fifo is not correct
output olc_oldue_pass_late_ue;
output olc_old_selhdr; // select header not data as outputs
output [3:0] olc_oldhq_wr_en; // header queue write-enable
output [ 1:0] olc_oldhq_rd_addr; // header queue read-addr
output olc_olddq0_wr_en; // data queue write-enable
// output [`SIO_OLD_RF_ADDRWIDTH-1:0] olc_olddq0_wr_addr; // data queue write-addr
output [4:0] olc_olddq0_wr_addr; // data queue write-addr
output olc_olddq0_rd_en; // data queue read-enable
// output [`SIO_OLD_RF_ADDRWIDTH-1:00] olc_olddq0_rd_addr; // data queue read-addr
output [4:0] olc_olddq0_rd_addr; // data queue read-addr
output olc_olddq1_wr_en; // data queue write-enable
// output [`SIO_OLD_RF_ADDRWIDTH-1:00] olc_olddq1_wr_addr; // data queue write-addr
output [4:0] olc_olddq1_wr_addr; // data queue write-addr
output olc_olddq1_rd_en; // data queue read-enable
// output [`SIO_OLD_RF_ADDRWIDTH-1:00] olc_olddq1_rd_addr; // data queue read-addr
output [4:0] olc_olddq1_rd_addr; // data queue read-addr
input l2sio_v_bit; // Response valid from L2 to SIO
input l2sio_r_bit; // read bit - 1 = read, 0=write
input l2sio_p_bit; // Posted bit - 1=no ack needed
input l2sio_j_bit; // Jtag bit - 1 = jtag
output olc_opcc_req; // request for olp bus
input opcc_olc_gnt; // transfer is granted
output sio_sii_olc_ilc_dequeue; // dequeued an request buffer entry
// output sio_sii_olc_ilc_data_dequeue; // dequeued a read buffer entry
output [1:0] ojc_old_wr_en; // store the jtag read data,
// [1]=load 8Bytes to head (63:32), [0]=load 8Bytes to tail
output ojc_old_jtagsr_en; // either store the jtag read data or
// shift out another bit from the head (lsb),
// shift bits [n:1] into [n-1:0]
// shift in a 0 to the tail [n]
///////////////////////////////////////
// Scan chain connections
///////////////////////////////////////
assign pce_ov = tcu_pce_ov;
assign stop = tcu_clk_stop;
sio_olc_ctl_l1clkhdr_ctl_macro clkgen (
cl_sc1_msff_8x ff_ojc_old_jtagsr_en (.l1clk(l1clk),
.q(ojc_old_jtagsr_en_r));
cl_u1_buf_32x spare0_buf_32x (.in(1'b1),
.out(spare0_buf_32x_unused));
cl_u1_nand3_8x spare0_nand3_8x (.in0(1'b1),
.out(spare0_nand3_8x_unused));
cl_u1_inv_8x spare0_inv_8x (.in(1'b1),
.out(spare0_inv_8x_unused));
cl_u1_aoi22_4x spare0_aoi22_4x (.in00(1'b1),
.out(spare0_aoi22_4x_unused));
cl_u1_buf_8x spare0_buf_8x (.in(1'b1),
.out(spare0_buf_8x_unused));
cl_u1_oai22_4x spare0_oai22_4x (.in00(1'b1),
.out(spare0_oai22_4x_unused));
cl_u1_inv_16x spare0_inv_16x (.in(1'b1),
.out(spare0_inv_16x_unused));
cl_u1_nand2_16x spare0_nand2_16x (.in0(1'b1),
.out(spare0_nand2_16x_unused));
cl_u1_nor3_4x spare0_nor3_4x (.in0(1'b0),
.out(spare0_nor3_4x_unused));
cl_u1_nand2_8x spare0_nand2_8x (.in0(1'b1),
.out(spare0_nand2_8x_unused));
cl_u1_buf_16x spare0_buf_16x (.in(1'b1),
.out(spare0_buf_16x_unused));
cl_u1_nor2_16x spare0_nor2_16x (.in0(1'b0),
.out(spare0_nor2_16x_unused));
cl_u1_inv_32x spare0_inv_32x (.in(1'b1),
.out(spare0_inv_32x_unused));
///////////////////////////////////////
// BEGIN JTAG RESPONSE SECTION
///////////////////////////////////////
assign ojc_old_wr_en[1:0] = {ojc_cycle_sol1, ojc_cycle_sol0};
assign ojc_old_jtagsr_en = |{ojc_old_jtagsr_en_l, ojc_old_jtagsr_en_r};
assign ojc_old_jtagsr_en_l = |{ojc_cycle_sol1, ojc_cycle_sol0, shcnt[5:0]};
assign ojc_cycle_soh0 = l2sio_v_bit & l2sio_j_bit;
assign ojc_ack_soh0 = l2sio_v_bit & ~l2sio_r_bit;
assign shcnt_next[5:0] = (ojc_cycle_sol1 | (|shcnt[5:0])) ? (shcnt[5:0] + 6'b000001) : 6'b000000;
sio_olc_ctl_msff_ctl_macro__width_4 ff_ojc_cycle_sox (
.scan_in(ff_ojc_cycle_sox_scanin),
.scan_out(ff_ojc_cycle_sox_scanout),
.din ({ojc_cycle_sol1, ojc_cycle_sol0, ojc_cycle_soh1, ojc_cycle_soh0}),
.dout ({ojc_opcc_sync, ojc_cycle_sol1, ojc_cycle_sol0, ojc_cycle_soh1}),
sio_olc_ctl_msff_ctl_macro__width_4 ff_ojc_ack_sox (
.scan_in(ff_ojc_ack_sox_scanin),
.scan_out(ff_ojc_ack_sox_scanout),
.din ({ojc_ack_sol1, ojc_ack_sol0, ojc_ack_soh1, ojc_ack_soh0}),
.dout ({ojc_opcc_ack, ojc_ack_sol1, ojc_ack_sol0, ojc_ack_soh1}),
sio_olc_ctl_msff_ctl_macro__width_6 ff_ojc_shcnt (
.scan_in(ff_ojc_shcnt_scanin),
.scan_out(ff_ojc_shcnt_scanout),
///////////////////////////////////////
// END JTAG RESPONSE SECTION
///////////////////////////////////////
///////////////////////////////////////
// BEGIN UE CONTROL SECTION
///////////////////////////////////////
assign olc_oldue_check_clrerr = olc_cycle_sol[0];
assign olc_oldue_check_en = ue_check_en;
assign olc_oldue_wr_en[3:0] = {4{ue_wr_en}} & {ue_wr_ptr[1:0] == 2'b11,
assign olc_oldue_rd_addr[1:0] = ue_rd_ptr[1:0];
assign olc_oldue_selfwd = olc_cycle_slph & was_notcutthru;
assign uestore_ = ~|olc_oldue_wr_en[3:0];
assign olc_oldue_pass_late_ue_l = l2sio_v_bit ? 1'b0 :l2b_sio_ue_err_r ? 1'b1 :
olc_oldue_pass_late_ue_r;
// flop the olc_oldue_selfwd setting....clear when we see the ue_we
sio_olc_ctl_msff_ctl_macro__width_1 ff_pass_late_ue (
.scan_in(ff_pass_late_ue_scanin),
.scan_out(ff_pass_late_ue_scanout),
.din (olc_oldue_pass_late_ue_l),
.dout (olc_oldue_pass_late_ue_r),
sio_olc_ctl_msff_ctl_macro__width_1 ff_l2b_sio_ue_err (
.scan_in(ff_l2b_sio_ue_err_scanin),
.scan_out(ff_l2b_sio_ue_err_scanout),
.din (olc_oldue_pass_late_ue_r),
.dout (olc_oldue_pass_late_ue),
///////////////////////////////////////
// END UE CONTROL SECTION
///////////////////////////////////////
/////////////////////////////////////////////
// BEGIN OLDHQ/OLDDQ OUTPUT SIGNALS SECTION
/////////////////////////////////////////////
assign olc_old_selhdr = olc_cycle_slph;
assign olc_oldhq_wr_en[3:0] = {4{olc_cycle_soh0}} & {hq_wr_ptr[1:0] == 2'b11,
assign olc_oldhq_rd_addr[1:0] = hq_rd_ptr[1:0];
assign olc_olddq0_wr_en = pq0_wr_en;
assign olc_olddq0_wr_addr[4:0] = pq_wr_ptr[5:1];
assign olc_olddq0_rd_en = pq0_rd_en;
assign olc_olddq0_rd_addr[4:0] = pq_rd_ptr[5:1];
assign olc_olddq1_wr_en = pq1_wr_en;
assign olc_olddq1_wr_addr[4:0] = pq_wr_ptr[5:1];
assign olc_olddq1_rd_en = pq1_rd_en;
assign olc_olddq1_rd_addr[4:0] = pq_rd_ptr[5:1];
/////////////////////////////////////////////
// END OLDHQ/OLDDQ OUTPUT SIGNALS SECTION
/////////////////////////////////////////////
/////////////////////////////////////////////
// BEGIN MAIN WRITE CONTROL SECTION
/////////////////////////////////////////////
/////////////////////////////////////////////
// PACKET CYCLE STATEMACHINE
/////////////////////////////////////////////
// initiate packet state SOH0 if
// it's not a jtag source AND
// it's a read response or nonposted
// (technically dmu is not allowed to send nonposted...)
// so really should be tag vld and nonposted AND ENT)
assign olc_cycle_soh0 = l2sio_v_bit & ~l2sio_j_bit & (l2sio_r_bit | ~l2sio_p_bit);
assign olc_nextcycleis_sol[15:0] = {olc_cycle_sol[14:0], olc_cycle_soh1};
sio_olc_ctl_msff_ctl_macro__width_17 ff_olc_cycle (
.scan_in(ff_olc_cycle_scanin),
.scan_out(ff_olc_cycle_scanout),
.din ({olc_nextcycleis_sol[15:0], olc_nextcycleis_soh1}),
.dout ({olc_cycle_sol[15:0], olc_cycle_soh1}),
/////////////////////////////////////////////
// HEADER QUEUE WRITE POINTER LOGIC
/////////////////////////////////////////////
// top bit is to tell wrap around case
// -- if top bit diff and lower bits identical, then all full
// -- if top bit same and lower bits identical, then all empty
/////////////////////////////////////////////
assign hq_wr_ptr_inc = olc_cycle_soh0;
assign olc_nextcycleis_soh1 = l2sio_v_bit & ~l2sio_j_bit & l2sio_r_bit;
assign hq_wr_ptr_next[2:0] = hq_wr_ptr_inc ? hq_wr_ptr_plus1[2:0] : hq_wr_ptr[2:0];
assign hq_wr_ptr_plus1[2:0] = hq_wr_ptr[2:0] + 3'b001;
sio_olc_ctl_msff_ctl_macro__width_3 ff_hq_wr_ptr (
.scan_in(ff_hq_wr_ptr_scanin),
.scan_out(ff_hq_wr_ptr_scanout),
.din (hq_wr_ptr_next[2:0]),
/////////////////////////////////////////////
// PAYLOAD WRITE POINTER LOGIC
/////////////////////////////////////////////
// - 16 cycles of 32bit per packet, 4 packet deep
// subdivided into an upper and lower half
// reading is to both simultaneously
/////////////////////////////////////////////
assign pq_wr_ptr_next[6:0] = pq_wr_ptr_inc ? pq_wr_ptr_plus1[6:0] : pq_wr_ptr[6:0];
assign pq_wr_ptr_plus1[6:0] = pq_wr_ptr[6:0] + 7'b0000001;
sio_olc_ctl_msff_ctl_macro__width_7 ff_pq_wr_ptr (
.scan_in(ff_pq_wr_ptr_scanin),
.scan_out(ff_pq_wr_ptr_scanout),
.din (pq_wr_ptr_next[6:0]),
sio_olc_ctl_msff_ctl_macro__width_2 ff_pq_wr_en (
.scan_in(ff_pq_wr_en_scanin),
.scan_out(ff_pq_wr_en_scanout),
.din ({pq1_nextwren, pq0_nextwren}),
.dout ({pq1_wr_en, pq0_wr_en}),
/////////////////////////////////////////////
// LOWER HALF PAYLOAD QUEUE
// start write-enable assertion next cycle when :
// we're writing the header this cycle OR
// (we're writing the upper half of the packet queue AND
// it's not the the 7th write of the upper half of the packet
/////////////////////////////////////////////
assign pq0_nextwren = olc_nextcycleis_soh1 | (pq1_wr_en & ~&pq_wr_ptr[3:1]);
assign pq0_wr_ptr_inc = pq0_wr_en;
/////////////////////////////////////////////
// UPPER HALF PAYLOAD QUEUE
// start write-enable assertion next cycle when :
// we're writing the lower half this cycle (always a pair)
/////////////////////////////////////////////
assign pq1_nextwren = pq0_wr_en;
assign pq1_wr_ptr_inc = pq1_wr_en;
/////////////////////////////////////////////
// Master payload queue write pointer increments whenever each half increments
/////////////////////////////////////////////
assign pq_wr_ptr_inc = pq0_wr_ptr_inc | pq1_wr_ptr_inc;
/////////////////////////////////////////////
// start parity check flop enable next cycle when :
// we're have flopped the header this cycle (header was on bus last cycle)
// (we've been accumulating and the NEXT cycle is dataF - starting from data0)
/////////////////////////////////////////////
assign ue_nextchecken = olc_cycle_soh1 | (ue_check_en & ~olc_cycle_sol[15]);
assign ue_nextwren = ue_check_en & olc_cycle_sol[15];
assign ue_wr_ptr_inc = ue_nextwren;
assign ue_wr_ptr_next[2:0] = ue_wr_ptr_inc ? ue_wr_ptr_plus1[2:0] : ue_wr_ptr[2:0];
sio_olc_ctl_msff_ctl_macro__width_2 ff_ue_en (
.scan_in(ff_ue_en_scanin),
.scan_out(ff_ue_en_scanout),
.din ({ue_nextchecken, ue_nextwren}),
.dout ({ue_check_en, ue_wr_en}),
assign ue_wr_ptr_plus1[2:0] = ue_wr_ptr[2:0] + 3'b001;
sio_olc_ctl_msff_ctl_macro__width_3 ff_ue_wr_ptr (
.scan_in(ff_ue_wr_ptr_scanin),
.scan_out(ff_ue_wr_ptr_scanout),
.din (ue_wr_ptr_next[2:0]),
/////////////////////////////////////////////
// END MAIN WRITE CONTROL SECTION
/////////////////////////////////////////////
/////////////////////////////////////////////
// BEGIN MAIN READ CONTROL SECTION
/////////////////////////////////////////////
/////////////////////////////////////////////
/////////////////////////////////////////////
// ok to make a request NEXT CYCLE if any of the following are true
// 0. we made a request and we don't see grant
// 1. it's not the case we're seeing grant now ==> headptr is correct
// header queue is not empty AND (1a or 1b)
// 1a. the current header points to a write
// 1b. the current header points to a read AND $L has been filled
// 2. it's the case we're seeing grant now ==> headptr is not correct until next cycle
// so we can only make a new request if ++headptr will not access the write entry
// it's currently a write then the current payload must be ready
// because we can't predict if the next entry is a read or a write
// OR it's currently a read then then the future payload must be ready
/////////////////////////////////////////////
assign olc_nextcycleis_slpr =
// case0 : we have made a request and don't see grant
(olc_cycle_slpr & ~opcc_olc_gnt) |
// case1 : initial request (~gnt) :
// header queue is not empty (header ptrs are different) AND
// ( it's a write-ack (no need to check for data payload ready) OR
// it's a read (check payload is ready) )
(~opcc_olc_gnt & ~header_access_same_entry &
(~oldhq_dout_r_bit | (oldhq_dout_r_bit & payload_ready))) |
// case2 : back-to-back request : we see grant now
// header queue won't be empty (the post increment hq read pointer != hq write pointer) AND
// ( future payload is guaranteed to be ready OR
// payload is ready now (even before incrementing pq read pointer)
// if it's currently a write because
// we can't predict if the next entry is a read or a write)
(opcc_olc_gnt & ~header_will_access_same_entry &
(~oldhq_dout_r_bit & payload_ready)));
assign olc_opcc_req = olc_cycle_slpr | (olc_cycle_slph & ~header_now_access_same_entry &
(~oldhq_dout_r_bit | (oldhq_dout_r_bit & future_payload_was_ready)));
assign olc_nextcycleis_slph = opcc_olc_gnt & olc_cycle_slpr;
// assign olc_nextcycleis_slpp[14:0] = {olc_cycle_slpp[13:0], (oldhq_dout_r_bit & olc_cycle_slph)};
sio_olc_ctl_msff_ctl_macro__width_2 ff_slp_cycle (
.scan_in(ff_slp_cycle_scanin),
.scan_out(ff_slp_cycle_scanout),
.din ({olc_nextcycleis_slph, olc_nextcycleis_slpr}),
.dout ({olc_cycle_slph, olc_cycle_slpr}),
assign header_access_same_entry = (hq_wr_ptr[2:0] == hq_rd_ptr[2:0]);
assign header_will_access_same_entry = (hq_wr_ptr[2:0] == hq_rd_ptr_plus1[2:0]);
sio_olc_ctl_msff_ctl_macro__width_1 ff_header_now_access_same_entry (
.scan_in(ff_header_now_access_same_entry_scanin),
.scan_out(ff_header_now_access_same_entry_scanout),
.din (header_will_access_same_entry),
.dout (header_now_access_same_entry),
// be speculatively early 1 cyle due to request-grant latency
// can't be earlier than 2 cycles after last piece of data
// because UE would not be available to drive
// pointer is not reliable if we're currently reading anything except the last chunk
// If we're filling a cacheline and will be early accessing the line
// this is the minimum write pointer threshold
// This value is set to 16 cycles - 2 (for UE) + 1 (req-gnt penalty) (fully accumulated with no ue forwarding)
// - 1 (header) - 8 (transfer all the data)
// = 6 cycles has been written for cut-through case with UE converted to poisoned parity
// assign same_line_write_above_threshold = &pq_wr_ptr[3:0]; // fully accumulated
assign notcutthru = (&pq_wr_ptr[3:0] & payload_access_same_line) | ~payload_access_same_line; // fully accumulated
assign same_line_write_above_threshold = (pq_wr_ptr[3]); // | (pq_wr_ptr[3:1] == 3'b011));
// ready if any of the following are true
// 1. we're accesing same cacheline and write has filled above the threshold (cut thru case)
// 2. we're not currently accessing the same line and we won't be accessing the same line
// (this ensures that if we're doing cut-thru, we won't jump ahead on the next one)
assign future_payload_ready = (~payload_access_same_line & ~payload_will_access_same_line) | (~payload_access_same_line & payload_will_access_same_line & same_line_write_above_threshold );
assign payload_ready = ( payload_access_same_line & same_line_write_above_threshold) |
(~payload_access_same_line & ~payload_will_access_same_line);
assign payload_access_same_line = (pq_wr_ptr[6:4] == pq_rd_ptr[6:4]);
assign payload_will_access_same_line = (pq_wr_ptr[6:4] == pq_rd_ptr_plus1[6:4]) | (pq_wr_ptr[6:4] == pq_rd_ptr_plus6[6:4]);
sio_olc_ctl_msff_ctl_macro__width_2 ff_payload_readys (
.scan_in(ff_payload_readys_scanin),
.scan_out(ff_payload_readys_scanout),
.din ({future_payload_ready, notcutthru}),
.dout ({future_payload_was_ready, was_notcutthru}),
/////////////////////////////////////////////
// HEADER QUEUE READ POINTER LOGIC
// UE QUEUE goes with header queue on the read side
/////////////////////////////////////////////
assign hq_rd_ptr_inc = olc_nextcycleis_slph;
assign ue_rd_ptr_inc_e1 = olc_nextcycleis_slph & oldhq_dout_r_bit;
assign hq_rd_ptr_next[2:0] = hq_rd_ptr_inc ? hq_rd_ptr_plus1[2:0] : hq_rd_ptr[2:0];
sio_olc_ctl_msff_ctl_macro__width_1 ff_ue_rd_ptr_inc (
.scan_in(ff_ue_rd_ptr_inc_scanin),
.scan_out(ff_ue_rd_ptr_inc_scanout),
assign hq_rd_ptr_plus1[2:0] = hq_rd_ptr[2:0] + 3'b001;
// increment_macro inc_hq_rd_ptr_plus1 (width=4) (
// .din ({1'b0, hq_rd_ptr[2:0]}),
// .dout ({hq_rd_ptr_dummybit, hq_rd_ptr_plus1[2:0]})
sio_olc_ctl_msff_ctl_macro__width_3 ff_hq_rd_ptr (
.scan_in(ff_hq_rd_ptr_scanin),
.scan_out(ff_hq_rd_ptr_scanout),
.din (hq_rd_ptr_next[2:0]),
/////////////////////////////////////////////
// PAYLOAD READ POINTER LOGIC - 8 cycles of 64bit per packet, 4 packet deep//
/////////////////////////////////////////////
sio_olc_ctl_msff_ctl_macro__width_1 ff_dequeue (
.scan_in(ff_dequeue_scanin),
.scan_out(ff_dequeue_scanout),
.dout (sio_sii_olc_ilc_dequeue),
/////////////////////////////////////////////
// Master payload queue read pointer increments each cycle
/////////////////////////////////////////////
assign pq_rd_ptr_inc = (olc_nextcycleis_slph & oldhq_dout_r_bit) |
assign pq1_nextrden = (olc_cycle_slpr & oldhq_dout_r_bit) | (|pq_rd_ptr[3:1] & ~&pq_rd_ptr[3:1]);
assign pq0_nextrden = (olc_cycle_slpr & oldhq_dout_r_bit) | (|pq_rd_ptr[3:1] & ~&pq_rd_ptr[3:1]);
assign pq_rd_ptr_next[6:0] = pq_rd_ptr_inc ? pq_rd_ptr_plus1[6:0] : pq_rd_ptr[6:0];
assign ue_rd_ptr_next[2:0] = ue_rd_ptr_inc ? ue_rd_ptr_plus1[2:0] : ue_rd_ptr[2:0];
assign pq_rd_ptr_plus1[6:0] = {pq_rd_ptr[6:1] + 6'b000001, 1'b0};
assign pq_rd_ptr_plus6[6:0] = {pq_rd_ptr[6:1] + 6'b000110, 1'b0};
sio_olc_ctl_msff_ctl_macro__width_7 ff_pq_rd_ptr (
.scan_in(ff_pq_rd_ptr_scanin),
.scan_out(ff_pq_rd_ptr_scanout),
.din (pq_rd_ptr_next[6:0]),
sio_olc_ctl_msff_ctl_macro__width_2 ff_pq_rd_en (
.scan_in(ff_pq_rd_en_scanin),
.scan_out(ff_pq_rd_en_scanout),
.din ({pq1_nextrden, pq0_nextrden}),
.dout ({pq1_rd_en, pq0_rd_en}),
assign ue_rd_ptr_plus1[2:0] = ue_rd_ptr[2:0] + 3'b001;
sio_olc_ctl_msff_ctl_macro__width_3 ff_ue_rd_ptr (
.scan_in(ff_ue_rd_ptr_scanin),
.scan_out(ff_ue_rd_ptr_scanout),
.din (ue_rd_ptr_next[2:0]),
/////////////////////////////////////////////
// Create flop r_bit for timing purpose
/////////////////////////////////////////////
sio_olc_ctl_msff_ctl_macro__width_1 ff_l2sio_r_bit0 (
.scan_in(ff_l2sio_r_bit0_scanin),
.scan_out(ff_l2sio_r_bit0_scanout),
sio_olc_ctl_msff_ctl_macro__width_1 ff_l2sio_r_bit1 (
.scan_in(ff_l2sio_r_bit1_scanin),
.scan_out(ff_l2sio_r_bit1_scanout),
sio_olc_ctl_msff_ctl_macro__width_1 ff_l2sio_r_bit2 (
.scan_in(ff_l2sio_r_bit2_scanin),
.scan_out(ff_l2sio_r_bit2_scanout),
sio_olc_ctl_msff_ctl_macro__width_1 ff_l2sio_r_bit3 (
.scan_in(ff_l2sio_r_bit3_scanin),
.scan_out(ff_l2sio_r_bit3_scanout),
assign pre_r_bit0 = olc_oldhq_wr_en[0] ? l2sio_r_bit : l2sio_r_bit0_r;
assign pre_r_bit1 = olc_oldhq_wr_en[1] ? l2sio_r_bit : l2sio_r_bit1_r;
assign pre_r_bit2 = olc_oldhq_wr_en[2] ? l2sio_r_bit : l2sio_r_bit2_r;
assign pre_r_bit3 = olc_oldhq_wr_en[3] ? l2sio_r_bit : l2sio_r_bit3_r;
always @ (pre_r_bit0 or pre_r_bit1 or pre_r_bit2 or pre_r_bit3 or hq_rd_ptr_next[1:0])
case (hq_rd_ptr_next[1:0]) //synopsys parallel_case full_case
2'b00 : pre_r_bit = pre_r_bit0;
2'b01 : pre_r_bit = pre_r_bit1;
2'b10 : pre_r_bit = pre_r_bit2;
2'b11 : pre_r_bit = pre_r_bit3;
sio_olc_ctl_msff_ctl_macro__width_1 ff_l2sio_r_bit (
.scan_in(ff_l2sio_r_bit_scanin),
.scan_out(ff_l2sio_r_bit_scanout),
.dout (oldhq_dout_r_bit),
/////////////////////////////////////////////
// END MAIN READ CONTROL SECTION
/////////////////////////////////////////////
supply0 vss; // <- port for ground
supply1 vdd; // <- port for power
assign ff_ojc_cycle_sox_scanin = so_0;
assign ff_ojc_ack_sox_scanin = ff_ojc_cycle_sox_scanout ;
assign ff_ojc_shcnt_scanin = ff_ojc_ack_sox_scanout ;
assign ff_pass_late_ue_scanin = ff_ojc_shcnt_scanout ;
assign ff_l2b_sio_ue_err_scanin = ff_pass_late_ue_scanout ;
assign ff_olc_cycle_scanin = ff_l2b_sio_ue_err_scanout;
assign ff_hq_wr_ptr_scanin = ff_olc_cycle_scanout ;
assign ff_pq_wr_ptr_scanin = ff_hq_wr_ptr_scanout ;
assign ff_pq_wr_en_scanin = ff_pq_wr_ptr_scanout ;
assign ff_ue_en_scanin = ff_pq_wr_en_scanout ;
assign ff_ue_wr_ptr_scanin = ff_ue_en_scanout ;
assign ff_slp_cycle_scanin = ff_ue_wr_ptr_scanout ;
assign ff_header_now_access_same_entry_scanin = ff_slp_cycle_scanout ;
assign ff_payload_readys_scanin = ff_header_now_access_same_entry_scanout;
assign ff_ue_rd_ptr_inc_scanin = ff_payload_readys_scanout;
assign ff_hq_rd_ptr_scanin = ff_ue_rd_ptr_inc_scanout ;
assign ff_dequeue_scanin = ff_hq_rd_ptr_scanout ;
assign ff_pq_rd_ptr_scanin = ff_dequeue_scanout ;
assign ff_pq_rd_en_scanin = ff_pq_rd_ptr_scanout ;
assign ff_ue_rd_ptr_scanin = ff_pq_rd_en_scanout ;
assign ff_l2sio_r_bit0_scanin = ff_ue_rd_ptr_scanout ;
assign ff_l2sio_r_bit1_scanin = ff_l2sio_r_bit0_scanout ;
assign ff_l2sio_r_bit2_scanin = ff_l2sio_r_bit1_scanout ;
assign ff_l2sio_r_bit3_scanin = ff_l2sio_r_bit2_scanout ;
assign ff_l2sio_r_bit_scanin = ff_l2sio_r_bit3_scanout ;
assign scan_out = ff_l2sio_r_bit_scanout ;
// any PARAMS parms go into naming of macro
module sio_olc_ctl_l1clkhdr_ctl_macro (
// any PARAMS parms go into naming of macro
module sio_olc_ctl_msff_ctl_macro__width_4 (
assign fdin[3:0] = din[3:0];
// any PARAMS parms go into naming of macro
module sio_olc_ctl_msff_ctl_macro__width_6 (
assign fdin[5:0] = din[5:0];
// any PARAMS parms go into naming of macro
module sio_olc_ctl_msff_ctl_macro__width_1 (
assign fdin[0:0] = din[0:0];
// any PARAMS parms go into naming of macro
module sio_olc_ctl_msff_ctl_macro__width_17 (
assign fdin[16:0] = din[16:0];
.so({so[15:0],scan_out}),
// any PARAMS parms go into naming of macro
module sio_olc_ctl_msff_ctl_macro__width_3 (
assign fdin[2:0] = din[2:0];
// any PARAMS parms go into naming of macro
module sio_olc_ctl_msff_ctl_macro__width_7 (
assign fdin[6:0] = din[6:0];
// any PARAMS parms go into naming of macro
module sio_olc_ctl_msff_ctl_macro__width_2 (
assign fdin[1:0] = din[1:0];