// © IBM Corp. 2020
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by
// the terms below; you may not use the files in this repository except in
// compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the
// License, the "Work" hereby includes implementations of the work of authorship
// in physical form.
//
// 2) Notwithstanding any terms to the contrary in the License, any licenses
// necessary for implementation of the Work that are available from OpenPOWER
// via the Power ISA End User License Agreement (EULA) are explicitly excluded
// hereunder, and may be obtained from OpenPOWER under the terms and conditions
// of the EULA.
//
// Unless required by applicable law or agreed to in writing, the reference design
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
// for the specific language governing permissions and limitations under the License.
//
// Additional rights, including the ability to physically implement a softcore that
// is compliant with the required sections of the Power ISA Specification, are
// available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be
// obtained (along with the Power ISA) here: https://openpowerfoundation.org.
`timescale 1 ns / 1 ns
//********************************************************************
//*
//* TITLE: Microcode Control
//*
//* NAME: iuq_uc_control.v
//*
//*********************************************************************
`include " tri_a2o.vh "
module iuq_uc_control (
vdd ,
gnd ,
clk ,
rst ,
pc_iu_func_sl_thold_0_b ,
pc_iu_sg_0 ,
force_t ,
d_mode ,
delay_lclkr ,
mpw1_b ,
mpw2_b ,
scan_in ,
scan_out ,
xu_iu_ucode_xer_val ,
xu_iu_ucode_xer ,
br_hold ,
flush_next ,
flush ,
flush_into_uc ,
np1_flush ,
flush_ifar ,
cp_uc_credit_free ,
cp_flush ,
uc_default_act ,
next_valid ,
new_command ,
new_instr ,
start_addr ,
xer_type ,
early_end ,
force_ep ,
fxm_type ,
new_cond ,
ra_valid ,
rom_ra ,
rom_act ,
data_valid ,
rom_data_even ,
rom_data_odd ,
rom_data_even_late ,
rom_data_odd_late ,
uc_val ,
uc_end ,
cplbuffer_full ,
ucode_valid ,
ucode_ifar_even ,
ucode_instr_even ,
ucode_instr_odd ,
ucode_ext_even ,
ucode_ext_odd
) ;
//parameter ucode_width = 72;
inout vdd ;
inout gnd ;
input clk ;
input rst ;
input pc_iu_func_sl_thold_0_b ;
input pc_iu_sg_0 ;
input force_t ;
input d_mode ;
input delay_lclkr ;
input mpw1_b ;
input mpw2_b ;
( * pin_data = " PIN_FUNCTION=/SCAN_IN/ " * )
input scan_in ;
( * pin_data = " PIN_FUNCTION=/SCAN_OUT/ " * )
output scan_out ;
input xu_iu_ucode_xer_val ;
input [ 57 : 63 ] xu_iu_ucode_xer ;
input br_hold ; // br_redirect requires hold on xer_type's
input flush_next ; // Flush new instruction
input flush ; // Flush current instruction
input flush_into_uc ; // Flush back into the middle of uCode sequence
input np1_flush ; // Skip flushed instruction and go to next
input [ 43 : 61 ] flush_ifar ; // ucode-style address & state to flush to
input cp_uc_credit_free ;
input cp_flush ;
input uc_default_act ;
input next_valid ; // early signal for act
input new_command ;
input [ 0 : 31 ] new_instr ;
input [ 0 : 8 ] start_addr ; // bit (9) is unused - always '0'
input xer_type ; // instruction uses XER: need to wait until XER guaranteed valid
input early_end ;
input force_ep ;
input fxm_type ;
input new_cond ; // If '1', will skip lines with skip_cond bit set
output ra_valid ;
output [ 0 : 8 ] rom_ra ; // read address
output rom_act ;
input data_valid ;
input [ 32 : 71 ] rom_data_even ;
input [ 32 : 71 ] rom_data_odd ;
input [ 0 : 31 ] rom_data_even_late ;
input [ 0 : 31 ] rom_data_odd_late ;
output uc_val ; // to uc_buffer
output uc_end ; // to uc_buffer
output cplbuffer_full ; // to uc_buffer
output [ 0 : 1 ] ucode_valid ;
output [ 42 : 61 ] ucode_ifar_even ; // old: EFF_IFAR
output [ 0 : 31 ] ucode_instr_even ;
output [ 0 : 31 ] ucode_instr_odd ;
output [ 0 : 3 ] ucode_ext_even ; // RT, S1, S2, S3
output [ 0 : 3 ] ucode_ext_odd ; // RT, S1, S2, S3
parameter xu_iu_ucode_xer_offset = 0 ;
parameter xu_iu_ucode_xer_val_offset = xu_iu_ucode_xer_offset + 7 ;
parameter wait_for_xer_offset = xu_iu_ucode_xer_val_offset + 1 ;
parameter xer_val_occurred_offset = wait_for_xer_offset + 1 ;
parameter valid_offset = xer_val_occurred_offset + 1 ;
parameter instr_offset = valid_offset + 1 ;
parameter instr_even_late_offset = instr_offset + 32 ;
parameter instr_odd_late_offset = instr_even_late_offset + 32 ;
parameter sel_even_late_offset = instr_odd_late_offset + 32 ;
parameter sel_odd_late_offset = sel_even_late_offset + 12 ;
parameter early_end_offset = sel_odd_late_offset + 11 ;
parameter cond_offset = early_end_offset + 1 ;
parameter rom_addr_offset = cond_offset + 1 ;
parameter flush_to_odd_offset = rom_addr_offset + 9 ;
parameter inloop_offset = flush_to_odd_offset + 1 ;
parameter count_offset = inloop_offset + 1 ;
parameter skip_zero_offset = count_offset + 5 ;
parameter skip_to_np1_offset = skip_zero_offset + 1 ;
parameter force_ep_offset = skip_to_np1_offset + 1 ;
parameter fxm_type_offset = force_ep_offset + 1 ;
parameter ep_force_even_late_offset = fxm_type_offset + 1 ;
parameter ep_force_odd_late_offset = ep_force_even_late_offset + 1 ;
parameter scan_right = ep_force_odd_late_offset + 1 - 1 ;
// Latches
wire [ 57 : 63 ] xu_iu_ucode_xer_d ;
wire xu_iu_ucode_xer_val_d ;
wire wait_for_xer_d ;
wire xer_val_occurred_d ;
wire valid_d ;
wire [ 0 : 31 ] instr_d ;
wire early_end_d ;
wire cond_d ;
wire [ 0 : 8 ] rom_addr_d ;
wire flush_to_odd_d ;
wire inLoop_d ;
wire [ 0 : 4 ] count_d ;
wire skip_zero_d ;
wire skip_to_np1_d ;
wire [ 57 : 63 ] xu_iu_ucode_xer_l2 ;
wire xu_iu_ucode_xer_val_l2 ;
wire wait_for_xer_l2 ;
wire xer_val_occurred_l2 ;
wire valid_l2 ;
wire [ 0 : 31 ] instr_l2 ;
wire early_end_l2 ;
wire cond_l2 ;
wire [ 0 : 8 ] rom_addr_l2 ;
wire flush_to_odd_l2 ;
wire inLoop_l2 ;
wire [ 0 : 4 ] count_l2 ;
wire skip_zero_l2 ;
wire skip_to_np1_l2 ;
wire force_ep_d ;
wire force_ep_l2 ;
wire fxm_type_d ;
wire fxm_type_l2 ;
wire shift_fxm ;
//
// Even
wire [ 0 : 31 ] template_code_even ;
wire uc_end_even ;
wire uc_end_early_even ;
wire loop_begin_even ;
wire loop_end_even ;
wire [ 0 : 2 ] count_src_even ;
wire [ 0 : 3 ] ext_even ;
wire sel0_5_even ;
wire [ 0 : 1 ] sel6_10_even ;
wire [ 0 : 1 ] sel11_15_even ;
wire [ 0 : 1 ] sel16_20_even ;
wire [ 0 : 1 ] sel21_25_even ;
wire sel26_30_even ;
wire sel31_even ;
wire cr_bf2fxm_even ; // for mtocrf
wire skip_cond_even ;
wire skip_zero_even ;
wire skip_nop_even ;
wire [ 0 : 9 ] loop_addr_even ;
wire [ 0 : 2 ] loop_init_even ;
wire ep_instr_even ;
wire ucode_end_even ;
wire [ 0 : 7 ] fxm ;
wire [ 0 : 31 ] nop ;
wire [ 0 : 3 ] nop_ext ;
wire use_nop_even ;
wire [ 0 : 31 ] uc_instruction_even ;
//timing fixes
wire sel0_5_even_late ;
wire [ 0 : 1 ] sel6_10_even_late ;
wire [ 0 : 1 ] sel11_15_even_late ;
wire [ 0 : 1 ] sel16_20_even_late ;
wire [ 0 : 1 ] sel21_25_even_late ;
wire sel26_30_even_late ;
wire sel31_even_late ;
wire use_nop_even_late ;
wire [ 0 : 11 ] sel_even_late_d ;
wire [ 0 : 11 ] sel_even_late_l2 ;
wire ep_force_even_late_d ;
wire ep_force_even_late_l2 ;
wire [ 0 : 31 ] instr_even_late_d ;
wire [ 0 : 31 ] instr_even_late_l2 ;
//
// Odd
wire [ 0 : 31 ] template_code_odd ;
wire uc_end_odd ;
wire uc_end_early_odd ;
wire loop_begin_odd ;
wire loop_end_odd ;
wire [ 0 : 2 ] count_src_odd ;
wire [ 0 : 3 ] ext_odd ;
wire sel0_5_odd ;
wire [ 0 : 1 ] sel6_10_odd ;
wire [ 0 : 1 ] sel11_15_odd ;
wire [ 0 : 1 ] sel16_20_odd ;
wire [ 0 : 1 ] sel21_25_odd ;
wire sel26_30_odd ;
wire sel31_odd ;
wire cr_bf2fxm_odd ; // for mtocrf
wire skip_cond_odd ;
wire skip_zero_odd ;
wire skip_nop_odd ;
wire [ 0 : 9 ] loop_addr_odd ;
wire [ 0 : 2 ] loop_init_odd ;
wire ep_instr_odd ;
wire ucode_end_odd ;
wire [ 0 : 31 ] uc_instruction_odd ;
//timing fixes
wire sel0_5_odd_late ;
wire [ 0 : 1 ] sel6_10_odd_late ;
wire [ 0 : 1 ] sel11_15_odd_late ;
wire [ 0 : 1 ] sel16_20_odd_late ;
wire [ 0 : 1 ] sel21_25_odd_late ;
wire sel26_30_odd_late ;
wire sel31_odd_late ;
wire [ 0 : 10 ] sel_odd_late_d ;
wire [ 0 : 10 ] sel_odd_late_l2 ;
wire ep_force_odd_late_d ;
wire ep_force_odd_late_l2 ;
wire [ 0 : 31 ] instr_odd_late_d ;
wire [ 0 : 31 ] instr_odd_late_l2 ;
//
// Combined
wire loop_begin ;
wire loop_end ;
wire [ 0 : 2 ] count_src ;
wire skip_zero ;
wire [ 0 : 8 ] loop_addr ; // bit (9) is unused (always '0')
wire [ 0 : 2 ] loop_init ;
wire ucode_end ;
// control
wire last_loop ;
wire last_loop_fast ;
wire loopback ;
wire inc_RT ;
wire xer_act ;
wire [ 0 : 4 ] NB_dec ;
wire [ 0 : 1 ] NB_comp ;
wire [ 0 : 6 ] XER_dec_z ;
wire [ 0 : 2 ] XER_low ;
wire [ 0 : 1 ] XER_comp ;
wire [ 0 : 4 ] count_init ;
wire skip_even ;
wire skip_odd ;
wire [ 0 : 31 ] buff_instr_in ;
wire cplbuffer_xer_act ;
wire cplbuffer_full_int ;
wire [ 0 : 31 ] oldest_instr ;
wire [ 57 : 63 ] oldest_xer ;
wire uc_control_act ;
wire tiup ;
wire [ 0 : scan_right ] siv ;
wire [ 0 : scan_right ] sov ;
wire buff_scan_in ;
wire buff_scan_out ;
( * analysis_not_referenced = " true " * )
wire [ 0 : 16 ] unused ;
//tidn <= '0';
assign tiup = 1 'b1 ;
//---------------------------------------------------------------------
// load new command
//---------------------------------------------------------------------
//???? Add act once new_command timing is ok (everything except xu_iu_ucode_xer_val)
//???? uc_act <= new_command or valid_l2;
assign uc_control_act = flush_into_uc | next_valid | data_valid ;
assign rom_act = uc_control_act ;
// Wait for 1 cycle after getting new command to allow IU to flush
assign valid_d = ( ( new_command & ( ~ flush_next ) ) | ( valid_l2 & ( ~ ( ucode_end & data_valid ) ) & ( ~ flush ) ) ) | flush_into_uc ;
assign uc_val = valid_l2 ;
// Don't need br_hold anymore because new_command checks this
assign wait_for_xer_d = ( flush = = 1 'b1 ) ? 1 'b0 : //flush_into_uc = '1'
( new_command = = 1 'b1 ) ? ( xer_type & ( ~ ( xu_iu_ucode_xer_val_l2 | xer_val_occurred_l2 ) ) ) :
( ( xu_iu_ucode_xer_val_l2 | xer_val_occurred_l2 ) = = 1 'b1 ) ? 1 'b0 :
wait_for_xer_l2 ;
// Set if xer_val comes before wait_for_xer (preissue sent, but valid is held off in uc_buffer)
// Clear when new_command (and don't set wait_for_xer hold), or clear on flush or br_hold
assign xer_val_occurred_d = ( xu_iu_ucode_xer_val_l2 | xer_val_occurred_l2 ) & ( ~ wait_for_xer_l2 ) & ( ~ new_command ) & ( ~ flush ) & ( ~ br_hold ) ;
assign instr_d [ 0 : 5 ] = ( flush_into_uc = = 1 'b1 ) ? oldest_instr [ 0 : 5 ] :
( new_command = = 1 'b1 ) ? new_instr [ 0 : 5 ] :
instr_l2 [ 0 : 5 ] ;
assign instr_d [ 6 : 10 ] = ( flush_into_uc = = 1 'b1 ) ? flush_ifar [ 49 : 53 ] :
( new_command = = 1 'b1 ) ? new_instr [ 6 : 10 ] :
( inc_RT = = 1 'b1 ) ? instr_l2 [ 6 : 10 ] + 5 'b00001 :
instr_l2 [ 6 : 10 ] ;
assign instr_d [ 11 ] = ( flush_into_uc = = 1 'b1 ) ? oldest_instr [ 11 ] :
( new_command = = 1 'b1 ) ? new_instr [ 11 ] :
instr_l2 [ 11 ] ;
// Note: we must never flush_into_uc for a fxm_type instruction because we don't keep that info
assign instr_d [ 12 : 19 ] = ( flush_into_uc = = 1 'b1 ) ? oldest_instr [ 12 : 19 ] :
( new_command = = 1 'b1 ) ? new_instr [ 12 : 19 ] :
( shift_fxm = = 1 'b1 ) ? { instr_l2 [ 14 : 19 ] , instr_l2 [ 12 : 13 ] } :
instr_l2 [ 12 : 19 ] ;
assign instr_d [ 20 : 31 ] = ( flush_into_uc = = 1 'b1 ) ? oldest_instr [ 20 : 31 ] :
( new_command = = 1 'b1 ) ? new_instr [ 20 : 31 ] :
instr_l2 [ 20 : 31 ] ;
assign early_end_d = ( flush_into_uc = = 1 'b1 ) ? oldest_instr [ 6 ] :
( new_command = = 1 'b1 ) ? early_end :
early_end_l2 ;
assign cond_d = ( flush_into_uc = = 1 'b1 ) ? oldest_instr [ 7 ] :
( new_command = = 1 'b1 ) ? new_cond :
cond_l2 ;
assign force_ep_d = ( flush_into_uc = = 1 'b1 ) ? oldest_instr [ 8 ] :
( new_command = = 1 'b1 ) ? force_ep :
force_ep_l2 ;
// Note: we must never flush_into_uc for a fxm_type instruction because we don't keep latest instr(12:19)
assign fxm_type_d = ( flush_into_uc = = 1 'b1 ) ? 1 'b0 :
( new_command = = 1 'b1 ) ? fxm_type : // for mtcrf
fxm_type_l2 ;
assign shift_fxm = fxm_type_l2 & data_valid ;
// uCode sequence cannot cross 256-instr address boundary
// Read 2 instructions at a time, so only need 9 bits
assign rom_addr_d = ( flush_into_uc = = 1 'b1 ) ? { oldest_instr [ 9 : 10 ] , flush_ifar [ 54 : 60 ] } :
( new_command = = 1 'b1 ) ? start_addr :
( loopback = = 1 'b1 ) ? loop_addr :
( data_valid = = 1 'b1 ) ? ( rom_addr_l2 [ 0 : 8 ] + 9 'b000000001 ) :
rom_addr_l2 ;
assign rom_ra = rom_addr_d ;
assign ra_valid = valid_d & ( ~ wait_for_xer_d ) & ( ~ br_hold ) & ( ~ cplbuffer_full_int ) ; // ???? should I change to just check next cycle, or leave as is in case we add other threads?
// If flushing to second half of pair, throw no-op into first position to keep things balanced.
assign flush_to_odd_d = ( flush_into_uc = = 1 'b1 ) ? flush_ifar [ 61 ] :
( new_command = = 1 'b1 ) ? 1 'b0 :
( data_valid = = 1 'b1 ) ? 1 'b0 :
flush_to_odd_l2 ;
//---------------------------------------------------------------------
// create output instruction - even
//---------------------------------------------------------------------
assign uc_end_even = rom_data_even [ 32 ] ;
assign uc_end_early_even = rom_data_even [ 33 ] ;
assign loop_begin_even = rom_data_even [ 34 ] ;
assign loop_end_even = rom_data_even [ 35 ] & ( inLoop_l2 | loop_begin_even ) ;
assign count_src_even = rom_data_even [ 36 : 38 ] ; // 00: NB(3:4), 01: "000" & 2's comp NB(3:4), 10: mult of 4 & XER(62:63), 11: 2's comp XER(62:63), 100: RT(inverted), 101: NB(0:2) - word mode, 110: XER(57:61) - word mode, 111: loop_init
assign ext_even [ 0 ] = rom_data_even [ 39 ] ; // RT -- ??? Can we incorporate into mux selects?
assign ext_even [ 1 ] = rom_data_even [ 40 ] ; // S1
assign ext_even [ 2 ] = rom_data_even [ 41 ] ; // S2
assign ext_even [ 3 ] = rom_data_even [ 42 ] ; // S3
assign sel0_5_even = rom_data_even [ 43 ] ;
assign sel6_10_even = rom_data_even [ 44 : 45 ] ;
assign sel11_15_even = rom_data_even [ 46 : 47 ] ;
assign sel16_20_even = rom_data_even [ 48 : 49 ] ;
assign sel21_25_even = rom_data_even [ 50 : 51 ] ;
assign sel26_30_even = rom_data_even [ 52 ] ;
assign sel31_even = rom_data_even [ 53 ] ;
assign cr_bf2fxm_even = rom_data_even [ 54 ] ;
assign skip_cond_even = rom_data_even [ 55 ] ;
assign skip_zero_even = rom_data_even [ 56 ] ; // For when XER = 0 & to help with NB coding
assign skip_nop_even = rom_data_even [ 57 ] ;
assign loop_addr_even = rom_data_even [ 58 : 67 ] ; // ??? In product, can latch loop_begin address instead of keeping in ROM
assign loop_init_even = rom_data_even [ 68 : 70 ] ;
assign ep_instr_even = rom_data_even [ 71 ] ;
assign template_code_even [ 0 : 26 ] = rom_data_even_late [ 0 : 26 ] ;
assign template_code_even [ 27 ] = rom_data_even_late [ 27 ] | ep_force_even_late_l2 ;
assign template_code_even [ 28 : 31 ] = rom_data_even_late [ 28 : 31 ] ;
assign sel_even_late_d [ 0 ] = sel0_5_even ;
assign sel_even_late_d [ 1 : 2 ] = sel6_10_even ;
assign sel_even_late_d [ 3 : 4 ] = sel11_15_even ;
assign sel_even_late_d [ 5 : 6 ] = sel16_20_even ;
assign sel_even_late_d [ 7 : 8 ] = sel21_25_even ;
assign sel_even_late_d [ 9 ] = sel26_30_even ;
assign sel_even_late_d [ 10 ] = sel31_even ;
assign sel_even_late_d [ 11 ] = use_nop_even ;
assign sel0_5_even_late = sel_even_late_l2 [ 0 ] ;
assign sel6_10_even_late = sel_even_late_l2 [ 1 : 2 ] ;
assign sel11_15_even_late = sel_even_late_l2 [ 3 : 4 ] ;
assign sel16_20_even_late = sel_even_late_l2 [ 5 : 6 ] ;
assign sel21_25_even_late = sel_even_late_l2 [ 7 : 8 ] ;
assign sel26_30_even_late = sel_even_late_l2 [ 9 ] ;
assign sel31_even_late = sel_even_late_l2 [ 10 ] ;
assign use_nop_even_late = sel_even_late_l2 [ 11 ] ;
assign ep_force_even_late_d = ep_instr_even & force_ep_l2 ;
assign ucode_end_even = ( uc_end_even | ( uc_end_early_even & early_end_l2 ) ) & ( ~ ( loop_end_even & ( ~ last_loop_fast ) ) ) ;
assign fxm = ( instr_l2 [ 6 : 8 ] = = 3 'b000 ) ? 8 'b10000000 :
( instr_l2 [ 6 : 8 ] = = 3 'b001 ) ? 8 'b01000000 :
( instr_l2 [ 6 : 8 ] = = 3 'b010 ) ? 8 'b00100000 :
( instr_l2 [ 6 : 8 ] = = 3 'b011 ) ? 8 'b00010000 :
( instr_l2 [ 6 : 8 ] = = 3 'b100 ) ? 8 'b00001000 :
( instr_l2 [ 6 : 8 ] = = 3 'b101 ) ? 8 'b00000100 :
( instr_l2 [ 6 : 8 ] = = 3 'b110 ) ? 8 'b00000010 :
8 'b00000001 ;
assign instr_even_late_d [ 0 : 10 ] = instr_l2 [ 0 : 10 ] ;
assign instr_even_late_d [ 11 : 20 ] = ( cr_bf2fxm_even = = 1 'b0 ) ? instr_l2 [ 11 : 20 ] :
{ 1 'b1 , fxm [ 0 : 7 ] , 1 'b0 } ;
assign instr_even_late_d [ 21 : 31 ] = instr_l2 [ 21 : 31 ] ;
assign uc_instruction_even [ 0 : 5 ] = ( sel0_5_even_late = = 1 'b0 ) ? template_code_even [ 0 : 5 ] :
instr_even_late_l2 [ 0 : 5 ] ;
assign uc_instruction_even [ 6 : 10 ] = ( sel6_10_even_late = = 2 'b00 ) ? template_code_even [ 6 : 10 ] :
( sel6_10_even_late = = 2 'b01 ) ? instr_even_late_l2 [ 6 : 10 ] :
( sel6_10_even_late = = 2 'b10 ) ? instr_even_late_l2 [ 11 : 15 ] :
instr_even_late_l2 [ 16 : 20 ] ;
assign uc_instruction_even [ 11 : 15 ] = ( sel11_15_even_late = = 2 'b00 ) ? template_code_even [ 11 : 15 ] :
( sel11_15_even_late = = 2 'b01 ) ? instr_even_late_l2 [ 11 : 15 ] :
( sel11_15_even_late = = 2 'b10 ) ? instr_even_late_l2 [ 16 : 20 ] :
instr_even_late_l2 [ 6 : 10 ] ;
assign uc_instruction_even [ 16 : 20 ] = ( sel16_20_even_late = = 2 'b00 ) ? template_code_even [ 16 : 20 ] :
( sel16_20_even_late = = 2 'b01 ) ? instr_even_late_l2 [ 16 : 20 ] :
( sel16_20_even_late = = 2 'b10 ) ? instr_even_late_l2 [ 6 : 10 ] :
instr_even_late_l2 [ 11 : 15 ] ;
assign uc_instruction_even [ 21 : 25 ] = ( sel21_25_even_late = = 2 'b00 ) ? template_code_even [ 21 : 25 ] :
( sel21_25_even_late = = 2 'b01 ) ? instr_even_late_l2 [ 21 : 25 ] :
instr_even_late_l2 [ 16 : 20 ] ;
assign uc_instruction_even [ 26 : 30 ] = ( sel26_30_even_late = = 1 'b0 ) ? template_code_even [ 26 : 30 ] :
instr_even_late_l2 [ 26 : 30 ] ;
assign uc_instruction_even [ 31 ] = ( sel31_even_late = = 1 'b0 ) ? template_code_even [ 31 ] :
instr_even_late_l2 [ 31 ] ;
assign nop = 32 'b01100000000000000000000000000000 ;
assign nop_ext = 4 'b0000 ;
assign use_nop_even = skip_even ;
assign ucode_instr_even = ( use_nop_even_late = = 1 'b1 ) ? nop :
uc_instruction_even ;
assign ucode_ext_even = ( use_nop_even = = 1 'b1 ) ? nop_ext :
ext_even ;
assign ucode_valid [ 0 ] = data_valid & ( ~ flush ) & ( ~ ( skip_even & skip_odd & ( ~ ucode_end ) ) ) ;
// Removed ucode_end_odd term from skip_odd. When we skip on ucode_end_odd (e.g. mtcrf,FXM(7)=0), we still end up with a nop or something on even side. Since uc_ib_done is only 1 bit, it assumes even side was the end.
assign ucode_valid [ 1 ] = data_valid & ( ~ flush ) & ( ~ skip_odd ) & ( ~ ucode_end_even ) & ( ~ ( loop_end_even & ( ~ last_loop ) ) ) ; // Handles loops with odd # of lines
assign ucode_ifar_even [ 42 : 61 ] = { rom_addr_l2 [ 1 ] , count_l2 , inLoop_l2 , instr_l2 [ 6 : 10 ] , rom_addr_l2 [ 2 : 8 ] , 1 'b0 } ;
assign unused [ 0 ] = skip_nop_even ;
assign unused [ 1 : 10 ] = loop_addr_even ;
//---------------------------------------------------------------------
// create output instruction - odd
//---------------------------------------------------------------------
assign uc_end_odd = rom_data_odd [ 32 ] ;
assign uc_end_early_odd = rom_data_odd [ 33 ] ;
assign loop_begin_odd = rom_data_odd [ 34 ] ;
assign loop_end_odd = rom_data_odd [ 35 ] & ( inLoop_l2 | loop_begin_even ) ;
assign count_src_odd = rom_data_odd [ 36 : 38 ] ; // 00: NB(3:4), 01: "000" & 2's comp NB(3:4), 10: mult of 4 & XER(62:63), 11: 2's comp XER(62:63), 100: RT(inverted), 101: NB(0:2) - word mode, 110: XER(57:61) - word mode, 111: loop_init
assign ext_odd [ 0 ] = rom_data_odd [ 39 ] ; // RT -- ??? Can we incorporate into mux selects?
assign ext_odd [ 1 ] = rom_data_odd [ 40 ] ; // S1
assign ext_odd [ 2 ] = rom_data_odd [ 41 ] ; // S2
assign ext_odd [ 3 ] = rom_data_odd [ 42 ] ; // S3
assign sel0_5_odd = rom_data_odd [ 43 ] ;
assign sel6_10_odd = rom_data_odd [ 44 : 45 ] ;
assign sel11_15_odd = rom_data_odd [ 46 : 47 ] ;
assign sel16_20_odd = rom_data_odd [ 48 : 49 ] ;
assign sel21_25_odd = rom_data_odd [ 50 : 51 ] ;
assign sel26_30_odd = rom_data_odd [ 52 ] ;
assign sel31_odd = rom_data_odd [ 53 ] ;
assign cr_bf2fxm_odd = rom_data_odd [ 54 ] ;
assign skip_cond_odd = rom_data_odd [ 55 ] ;
assign skip_zero_odd = rom_data_odd [ 56 ] ; // For when XER = 0 & to help with NB coding
assign skip_nop_odd = rom_data_odd [ 57 ] ;
assign loop_addr_odd = rom_data_odd [ 58 : 67 ] ; // ??? In product, can latch loop_begin address instead of keeping in ROM
assign loop_init_odd = rom_data_odd [ 68 : 70 ] ;
assign ep_instr_odd = rom_data_odd [ 71 ] ;
assign template_code_odd [ 0 : 26 ] = rom_data_odd_late [ 0 : 26 ] ;
assign template_code_odd [ 27 ] = rom_data_odd_late [ 27 ] | ep_force_odd_late_l2 ;
assign template_code_odd [ 28 : 31 ] = rom_data_odd_late [ 28 : 31 ] ;
assign sel_odd_late_d [ 0 ] = sel0_5_odd ;
assign sel_odd_late_d [ 1 : 2 ] = sel6_10_odd ;
assign sel_odd_late_d [ 3 : 4 ] = sel11_15_odd ;
assign sel_odd_late_d [ 5 : 6 ] = sel16_20_odd ;
assign sel_odd_late_d [ 7 : 8 ] = sel21_25_odd ;
assign sel_odd_late_d [ 9 ] = sel26_30_odd ;
assign sel_odd_late_d [ 10 ] = sel31_odd ;
assign sel0_5_odd_late = sel_odd_late_l2 [ 0 ] ;
assign sel6_10_odd_late = sel_odd_late_l2 [ 1 : 2 ] ;
assign sel11_15_odd_late = sel_odd_late_l2 [ 3 : 4 ] ;
assign sel16_20_odd_late = sel_odd_late_l2 [ 5 : 6 ] ;
assign sel21_25_odd_late = sel_odd_late_l2 [ 7 : 8 ] ;
assign sel26_30_odd_late = sel_odd_late_l2 [ 9 ] ;
assign sel31_odd_late = sel_odd_late_l2 [ 10 ] ;
assign ep_force_odd_late_d = ep_instr_odd & force_ep_l2 ;
assign ucode_end_odd = ( uc_end_odd | ( uc_end_early_odd & early_end_l2 ) ) &
( ~ ( ( loop_end_odd | loop_end_even ) & ( ~ last_loop_fast ) ) ) ;
assign instr_odd_late_d [ 0 : 10 ] = instr_l2 [ 0 : 10 ] ;
assign instr_odd_late_d [ 11 : 20 ] = ( cr_bf2fxm_odd = = 1 'b0 ) ? instr_l2 [ 11 : 20 ] :
{ 1 'b1 , fxm [ 0 : 7 ] , 1 'b0 } ;
assign instr_odd_late_d [ 21 : 31 ] = instr_l2 [ 21 : 31 ] ;
assign uc_instruction_odd [ 0 : 5 ] = ( sel0_5_odd_late = = 1 'b0 ) ? template_code_odd [ 0 : 5 ] :
instr_odd_late_l2 [ 0 : 5 ] ;
assign uc_instruction_odd [ 6 : 10 ] = ( sel6_10_odd_late = = 2 'b00 ) ? template_code_odd [ 6 : 10 ] :
( sel6_10_odd_late = = 2 'b01 ) ? instr_odd_late_l2 [ 6 : 10 ] :
( sel6_10_odd_late = = 2 'b10 ) ? instr_odd_late_l2 [ 11 : 15 ] :
instr_odd_late_l2 [ 16 : 20 ] ;
assign uc_instruction_odd [ 11 : 15 ] = ( sel11_15_odd_late = = 2 'b00 ) ? template_code_odd [ 11 : 15 ] :
( sel11_15_odd_late = = 2 'b01 ) ? instr_odd_late_l2 [ 11 : 15 ] :
( sel11_15_odd_late = = 2 'b10 ) ? instr_odd_late_l2 [ 16 : 20 ] :
instr_odd_late_l2 [ 6 : 10 ] ;
assign uc_instruction_odd [ 16 : 20 ] = ( sel16_20_odd_late = = 2 'b00 ) ? template_code_odd [ 16 : 20 ] :
( sel16_20_odd_late = = 2 'b01 ) ? instr_odd_late_l2 [ 16 : 20 ] :
( sel16_20_odd_late = = 2 'b10 ) ? instr_odd_late_l2 [ 6 : 10 ] :
instr_odd_late_l2 [ 11 : 15 ] ;
assign uc_instruction_odd [ 21 : 25 ] = ( sel21_25_odd_late = = 2 'b00 ) ? template_code_odd [ 21 : 25 ] :
( sel21_25_odd_late = = 2 'b01 ) ? instr_odd_late_l2 [ 21 : 25 ] :
instr_odd_late_l2 [ 16 : 20 ] ;
assign uc_instruction_odd [ 26 : 30 ] = ( sel26_30_odd_late = = 1 'b0 ) ? template_code_odd [ 26 : 30 ] :
instr_odd_late_l2 [ 26 : 30 ] ;
assign uc_instruction_odd [ 31 ] = ( sel31_odd_late = = 1 'b0 ) ? template_code_odd [ 31 ] :
instr_odd_late_l2 [ 31 ] ;
assign ucode_instr_odd = uc_instruction_odd ;
assign ucode_ext_odd = ext_odd ;
assign unused [ 11 ] = loop_begin_odd ;
assign unused [ 12 ] = skip_zero_odd ;
assign unused [ 13 : 15 ] = loop_init_odd ;
assign unused [ 16 ] = loop_addr_odd [ 9 ] ;
//---------------------------------------------------------------------
// combine even & odd info
//---------------------------------------------------------------------
assign loop_begin = loop_begin_even ;
assign loop_end = loop_end_odd | loop_end_even ;
assign count_src = ( inLoop_l2 = = 1 'b1 ) ? count_src_odd :
count_src_even ;
assign skip_zero = skip_zero_even ;
assign loop_addr = loop_addr_odd [ 0 : 8 ] ;
assign loop_init = loop_init_even ;
assign ucode_end = ucode_end_even | ucode_end_odd ;
assign uc_end = ucode_end & data_valid ;
//---------------------------------------------------------------------
// control, state machines
//---------------------------------------------------------------------
// Old Assumptions:
// ??? No Nested Loops
// ??? All Loops must have at least 2 instructions??
// ??? New ucode instructions will be held off until XU flushes IU (to next instruction) on this thread
// ??? If loop_end is skip_c, the instruction before loop_end must also be skip_c
//
// New Assumptions:
// ??? No Nested Loops
// ??? Loops can have only 1 instruction
// ??? uCode cannot end in the same row as loop_begin
// ??? If loop_end is skip_c, the instruction before loop_end must also be skip_c
// ??? Loops must begin on an even address
// ??? Loops can end on an even address, but loop_address must be written in the odd side (loop_address_odd)
// ??? We can skip nop lines. They must be in the odd side, and marked skip_nop
assign inLoop_d = ( flush_into_uc = = 1 'b1 ) ? flush_ifar [ 48 ] :
( new_command = = 1 'b1 ) ? 1 'b0 : // clear when beginning
( ( ( data_valid & loop_begin ) | inLoop_l2 ) & ( ~ ( ( data_valid & loop_end ) & last_loop ) ) & valid_l2 ) ;
assign last_loop = ( count_l2 = = 5 'b00000 & inLoop_l2 ) |
( loop_begin & count_init = = 5 'b00000 ) |
( skip_zero & loop_begin & count_init = = 5 'b00001 ) |
( skip_zero_l2 & count_l2 = = 5 'b00001 ) |
( skip_cond_odd & loop_end_odd & cond_l2 ) |
( skip_cond_even & loop_end_even & cond_l2 ) ; // ??? Could remove this line if timing bad
// only for uc_end: never have loop_begin & uc_end in same rom line
assign last_loop_fast = ( count_l2 = = 5 'b00000 & inLoop_l2 ) |
( skip_zero_l2 & count_l2 = = 5 'b00001 ) |
( skip_cond_odd & loop_end_odd & cond_l2 ) |
( skip_cond_even & loop_end_even & cond_l2 ) ;
assign loopback = data_valid & loop_end & ( ~ last_loop ) ;
assign inc_RT = data_valid & loop_end & ( ~ ( skip_zero_l2 & count_l2 = = 5 'b00000 & ( ~ loop_begin ) ) ) &
( ~ ( skip_zero & loop_begin & count_init = = 5 'b00000 ) ) &
count_src [ 0 ] & ( ~ ( count_src = = 3 'b111 ) ) ; // load/store multiple & string op word loops
assign NB_dec = instr_l2 [ 16 : 20 ] - 5 'b00001 ;
// when NB(3:4) = 00 -> 00, 01 -> 11, 10 -> 10, 11 -> 01
assign NB_comp [ 0 ] = instr_l2 [ 19 ] ^ instr_l2 [ 20 ] ;
assign NB_comp [ 1 ] = instr_l2 [ 20 ] ;
assign xer_act = flush_into_uc | xu_iu_ucode_xer_val ;
assign xu_iu_ucode_xer_d = ( flush_into_uc = = 1 'b1 ) ? oldest_xer :
xu_iu_ucode_xer ;
assign xu_iu_ucode_xer_val_d = xu_iu_ucode_xer_val & ( ~ flush ) & ( ~ br_hold ) ; // flush term avoids problems with cplbuffer
assign XER_dec_z = ( xu_iu_ucode_xer_l2 [ 57 : 63 ] = = 7 'b0 ) ? 7 'b0000000 :
xu_iu_ucode_xer_l2 [ 57 : 63 ] - 7 'b0000001 ;
assign XER_low = ( XER_dec_z [ 5 : 6 ] = = 2 'b11 ) ? 3 'b100 :
{ 1 'b0 , xu_iu_ucode_xer_l2 [ 62 : 63 ] } ;
assign XER_comp [ 0 ] = xu_iu_ucode_xer_l2 [ 62 ] ^ xu_iu_ucode_xer_l2 [ 63 ] ;
assign XER_comp [ 1 ] = xu_iu_ucode_xer_l2 [ 63 ] ;
assign count_init = ( count_src = = 3 'b000 ) ? { 3 'b000 , NB_dec [ 3 : 4 ] } :
( count_src = = 3 'b001 ) ? { 3 'b000 , NB_comp [ 0 : 1 ] } :
( count_src = = 3 'b010 ) ? { 2 'b00 , XER_low } :
( count_src = = 3 'b011 ) ? { 3 'b000 , XER_comp [ 0 : 1 ] } :
( count_src = = 3 'b100 ) ? ( ~ ( instr_l2 [ 6 : 10 ] ) ) : // RT
( count_src = = 3 'b101 ) ? { 2 'b00 , NB_dec [ 0 : 2 ] } :
( count_src = = 3 'b110 ) ? XER_dec_z [ 0 : 4 ] :
{ 2 'b00 , loop_init } ;
assign count_d = ( flush_into_uc = = 1 'b1 ) ? flush_ifar [ 43 : 47 ] :
( ( data_valid & loop_begin & ( ~ inLoop_l2 ) & loop_end ) = = 1 'b1 ) ? count_init - 5 'b00001 :
( ( data_valid & loop_begin & ( ~ inLoop_l2 ) ) = = 1 'b1 ) ? count_init :
( ( data_valid & loop_end ) = = 1 'b1 ) ? count_l2 - 5 'b00001 :
count_l2 ;
assign skip_zero_d = ( ( ( data_valid & loop_end & last_loop ) | new_command | flush_into_uc ) = = 1 'b1 ) ? 1 'b0 : // added last_loop to handle 2 instruction loops in lswi,lswx
( ( data_valid & loop_begin ) = = 1 'b1 ) ? skip_zero :
skip_zero_l2 ;
// ??? If we always read each cycle, could we just do: skip_to_np1_d <- flush_into_uc and np1_flush?
assign skip_to_np1_d = ( flush = = 1 'b1 ) ? flush_into_uc & np1_flush :
( data_valid = = 1 'b1 ) ? 1 'b0 :
skip_to_np1_l2 ;
assign skip_even = ( ( ( skip_zero & loop_begin ) | skip_zero_l2 ) & ( count_l2 = = 5 'b00000 ) & inLoop_l2 ) |
( ( skip_zero & loop_begin ) & count_init = = 5 'b00000 & ( ~ inLoop_l2 ) ) |
( skip_cond_even & cond_l2 ) |
( fxm_type_l2 & instr_l2 [ 12 ] = = 1 'b0 ) |
flush_to_odd_l2 |
skip_to_np1_l2 ;
assign skip_odd = ( ( ( skip_zero & loop_begin ) | skip_zero_l2 ) & ( count_l2 = = 5 'b00000 ) & inLoop_l2 ) |
( ( skip_zero & loop_begin ) & count_init = = 5 'b00000 & ( ~ inLoop_l2 ) ) |
( skip_cond_odd & cond_l2 ) |
( fxm_type_l2 & instr_l2 [ 13 ] = = 1 'b0 ) |
skip_nop_odd |
( flush_to_odd_l2 & skip_to_np1_l2 ) ;
//---------------------------------------------------------------------
// Buffer old instructions until they complete
//---------------------------------------------------------------------
assign buff_instr_in = { instr_l2 [ 0 : 5 ] , early_end_l2 , cond_l2 , force_ep_l2 , rom_addr_l2 [ 0 : 1 ] , instr_l2 [ 11 : 31 ] } ;
assign cplbuffer_xer_act = ( wait_for_xer_l2 & xu_iu_ucode_xer_val_l2 ) |
( ( ~ wait_for_xer_l2 ) & new_command & xer_type & ( xer_val_occurred_l2 | xu_iu_ucode_xer_val_l2 ) ) ;
// Flush_into_uc requirements:
// -- signal active for only 1 cycle
// -- flush_into_uc can only occur if we have a non-completed uCode instruction
// -- flush_into_uc must not occur on fxm_type instr (we don't keep around instr_l2(12:19) in ifar)
iuq_uc_cplbuffer iuq_uc_cplbuffer0 (
. vdd ( vdd ) ,
. gnd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. pc_iu_func_sl_thold_0_b ( pc_iu_func_sl_thold_0_b ) ,
. pc_iu_sg_0 ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. d_mode ( d_mode ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. scan_in ( buff_scan_in ) ,
. scan_out ( buff_scan_out ) ,
. cp_uc_credit_free ( cp_uc_credit_free ) ,
. flush ( cp_flush ) ,
. flush_into_uc ( flush_into_uc ) ,
. new_command ( new_command ) ,
. flush_next ( flush_next ) ,
. valid_l2 ( valid_l2 ) ,
. flush_current ( flush ) ,
. buff_instr_in ( buff_instr_in ) ,
. cplbuffer_xer_act ( cplbuffer_xer_act ) ,
. wait_for_xer_l2 ( wait_for_xer_l2 ) ,
. xu_iu_ucode_xer_l2 ( xu_iu_ucode_xer_l2 ) ,
. cplbuffer_full ( cplbuffer_full_int ) ,
. oldest_instr ( oldest_instr ) ,
. oldest_xer ( oldest_xer )
) ;
assign cplbuffer_full = cplbuffer_full_int ;
//---------------------------------------------------------------------
// Latches
//---------------------------------------------------------------------
tri_rlmreg_p # ( . WIDTH ( 7 ) , . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) xu_iu_ucode_xer_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( xer_act ) , // ??? If change, make sure xer bugspray is still accurate
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ xu_iu_ucode_xer_offset: xu_iu_ucode_xer_offset + 7 - 1 ] ) ,
. scout ( sov [ xu_iu_ucode_xer_offset: xu_iu_ucode_xer_offset + 7 - 1 ] ) ,
. din ( xu_iu_ucode_xer_d ) ,
. dout ( xu_iu_ucode_xer_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) xu_iu_ucode_xer_val_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_default_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ xu_iu_ucode_xer_val_offset ] ) ,
. scout ( sov [ xu_iu_ucode_xer_val_offset ] ) ,
. din ( xu_iu_ucode_xer_val_d ) ,
. dout ( xu_iu_ucode_xer_val_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) wait_for_xer_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_default_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ wait_for_xer_offset ] ) ,
. scout ( sov [ wait_for_xer_offset ] ) ,
. din ( wait_for_xer_d ) ,
. dout ( wait_for_xer_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) xer_val_occurred_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( tiup ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ xer_val_occurred_offset ] ) ,
. scout ( sov [ xer_val_occurred_offset ] ) ,
. din ( xer_val_occurred_d ) ,
. dout ( xer_val_occurred_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) valid_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_default_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ valid_offset ] ) ,
. scout ( sov [ valid_offset ] ) ,
. din ( valid_d ) ,
. dout ( valid_l2 )
) ;
tri_rlmreg_p # ( . WIDTH ( 32 ) , . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) instr_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ instr_offset: instr_offset + 32 - 1 ] ) ,
. scout ( sov [ instr_offset: instr_offset + 32 - 1 ] ) ,
. din ( instr_d ) ,
. dout ( instr_l2 )
) ;
tri_rlmreg_p # ( . WIDTH ( 32 ) , . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) instr_even_late_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( data_valid ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ instr_even_late_offset: instr_even_late_offset + 32 - 1 ] ) ,
. scout ( sov [ instr_even_late_offset: instr_even_late_offset + 32 - 1 ] ) ,
. din ( instr_even_late_d ) ,
. dout ( instr_even_late_l2 )
) ;
tri_rlmreg_p # ( . WIDTH ( 32 ) , . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) instr_odd_late_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( data_valid ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ instr_odd_late_offset: instr_odd_late_offset + 32 - 1 ] ) ,
. scout ( sov [ instr_odd_late_offset: instr_odd_late_offset + 32 - 1 ] ) ,
. din ( instr_odd_late_d ) ,
. dout ( instr_odd_late_l2 )
) ;
tri_rlmreg_p # ( . WIDTH ( 12 ) , . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) sel_even_late_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( data_valid ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ sel_even_late_offset: sel_even_late_offset + 12 - 1 ] ) ,
. scout ( sov [ sel_even_late_offset: sel_even_late_offset + 12 - 1 ] ) ,
. din ( sel_even_late_d ) ,
. dout ( sel_even_late_l2 )
) ;
tri_rlmreg_p # ( . WIDTH ( 11 ) , . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) sel_odd_late_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( data_valid ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ sel_odd_late_offset: sel_odd_late_offset + 11 - 1 ] ) ,
. scout ( sov [ sel_odd_late_offset: sel_odd_late_offset + 11 - 1 ] ) ,
. din ( sel_odd_late_d ) ,
. dout ( sel_odd_late_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) early_end_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ early_end_offset ] ) ,
. scout ( sov [ early_end_offset ] ) ,
. din ( early_end_d ) ,
. dout ( early_end_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) cond_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ cond_offset ] ) ,
. scout ( sov [ cond_offset ] ) ,
. din ( cond_d ) ,
. dout ( cond_l2 )
) ;
tri_rlmreg_p # ( . WIDTH ( 9 ) , . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) rom_addr_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ rom_addr_offset: rom_addr_offset + 9 - 1 ] ) ,
. scout ( sov [ rom_addr_offset: rom_addr_offset + 9 - 1 ] ) ,
. din ( rom_addr_d ) ,
. dout ( rom_addr_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) flush_to_odd_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ flush_to_odd_offset ] ) ,
. scout ( sov [ flush_to_odd_offset ] ) ,
. din ( flush_to_odd_d ) ,
. dout ( flush_to_odd_l2 )
) ;
tri_rlmreg_p # ( . WIDTH ( 5 ) , . INIT ( 0 ) , . NEEDS_SRESET ( 0 ) ) count_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ count_offset: count_offset + 5 - 1 ] ) ,
. scout ( sov [ count_offset: count_offset + 5 - 1 ] ) ,
. din ( count_d ) ,
. dout ( count_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) inloop_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ inloop_offset ] ) ,
. scout ( sov [ inloop_offset ] ) ,
. din ( inLoop_d ) ,
. dout ( inLoop_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) skip_zero_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ skip_zero_offset ] ) ,
. scout ( sov [ skip_zero_offset ] ) ,
. din ( skip_zero_d ) ,
. dout ( skip_zero_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) skip_to_np1_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ skip_to_np1_offset ] ) ,
. scout ( sov [ skip_to_np1_offset ] ) ,
. din ( skip_to_np1_d ) ,
. dout ( skip_to_np1_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) force_ep_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ force_ep_offset ] ) ,
. scout ( sov [ force_ep_offset ] ) ,
. din ( force_ep_d ) ,
. dout ( force_ep_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) fxm_type_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( uc_control_act ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ fxm_type_offset ] ) ,
. scout ( sov [ fxm_type_offset ] ) ,
. din ( fxm_type_d ) ,
. dout ( fxm_type_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) ep_force_even_late_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( data_valid ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ ep_force_even_late_offset ] ) ,
. scout ( sov [ ep_force_even_late_offset ] ) ,
. din ( ep_force_even_late_d ) ,
. dout ( ep_force_even_late_l2 )
) ;
tri_rlmlatch_p # ( . INIT ( 0 ) , . NEEDS_SRESET ( 1 ) ) ep_force_odd_late_latch (
. vd ( vdd ) ,
. gd ( gnd ) ,
. clk ( clk ) ,
. rst ( rst ) ,
. act ( data_valid ) ,
. thold_b ( pc_iu_func_sl_thold_0_b ) ,
. sg ( pc_iu_sg_0 ) ,
. force_t ( force_t ) ,
. delay_lclkr ( delay_lclkr ) ,
. mpw1_b ( mpw1_b ) ,
. mpw2_b ( mpw2_b ) ,
. d_mode ( d_mode ) ,
. scin ( siv [ ep_force_odd_late_offset ] ) ,
. scout ( sov [ ep_force_odd_late_offset ] ) ,
. din ( ep_force_odd_late_d ) ,
. dout ( ep_force_odd_late_l2 )
) ;
//---------------------------------------------------------------------
// Scan
//---------------------------------------------------------------------
assign siv [ 0 : scan_right ] = { sov [ 1 : scan_right ] , scan_in } ;
assign buff_scan_in = sov [ 0 ] ;
assign scan_out = buff_scan_out ;
endmodule