OpenCores
URL https://opencores.org/ocsvn/sparc64soc/sparc64soc/trunk

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-CPU/] [spu/] [spu_mactl.v] - Rev 2

Compare with Previous | Blame | View Log

// ========== Copyright Header Begin ==========================================
// 
// OpenSPARC T1 Processor File: spu_mactl.v
// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// 
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// 
// The above named 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 work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// 
// ========== Copyright Header End ============================================
////////////////////////////////////////////////////////////////////////
/*
//      Description:    control for MA. 
*/
////////////////////////////////////////////////////////////////////////
// Global header file includes
////////////////////////////////////////////////////////////////////////
 
 
module spu_mactl (
 
/*outputs*/
spu_mactl_iss_pulse,
spu_mactl_mpa_wen,
spu_mactl_maaddr_wen,
spu_mactl_manp_wen,
 
spu_mactl_ldop,
spu_mactl_stop,
spu_mactl_mulop,
spu_mactl_redop,
spu_mactl_expop,
 
spu_mactl_memmxsel_l,
 
spu_mactl_memeve_wen,
spu_mactl_memodd_wen,
 
spu_mactl_mamem_ren,
spu_mactl_mamem_wen,
 
spu_mactl_iss_pulse_dly,
 
spu_mactl_ldxa_data_w_sel_l,
spu_mactl_ldxa_data_w_select,
 
spu_mactl_mpa_sel,
 
spu_mactl_madp_parflop_wen,
 
spu_lsu_ldxa_data_vld_w2,
spu_lsu_ldxa_tid_w2,
spu_lsu_stxa_ack,
 
spu_lsu_stxa_ack_tid,
 
spu_mactl_ldxa_mactl_reg,
 
spu_mactl_force_perr,
 
spu_ifu_ttype_w2,
spu_ifu_ttype_vld_w2,
spu_ifu_ttype_tid_w,
 
spu_tlu_rsrv_illgl_m,
 
 
spu_ifu_corr_err_w2,
spu_ifu_unc_err_w,
spu_lsu_unc_error_w,
 
spu_ifu_mamem_err_w,
spu_ifu_int_w2,
spu_lsu_ldxa_illgl_va_w2,
 
 
spu_mactl_streq,
 
spu_mactl_ctl_reset,
spu_mactl_mem_reset_l,
 
 
spu_mactl_ma_kill_op,
 
spu_mactl_stxa_force_abort,
 
spu_mactl_mactl_len,
 
spu_mactl_uncerr_rst,
 
spu_mactl_iss_pulse_pre,
 
spu_mactl_pcx_wen,
spu_mactl_pcx_7170_sel,
 
spu_mactl_perr_set,
 
/*inputs*/
 
spu_mast_streq,
 
 
lsu_spu_stb_empty,
 
spu_maaddr_maaddr_0,
spu_maaddr_mpa_3,
 
spu_mald_memwen,
spu_mamul_memwen,
spu_mamul_memren,
spu_maaeqb_memwen,
spu_maaeqb_memren,
 
spu_mared_memren,
spu_mared_memwen,
 
spu_mast_memren,
 
lsu_spu_early_flush_g,
tlu_spu_flush_w,
ifu_spu_flush_w,
ifu_spu_inst_vld_w,
lsu_spu_asi_state_e,
ifu_lsu_ld_inst_e,
ifu_lsu_st_inst_e,
ifu_lsu_alt_space_e,
ifu_tlu_thrid_e,
exu_lsu_ldst_va_e,
 
spu_mald_done_set,
spu_mast_done_set,
spu_mared_done_set,
spu_maexp_done_set,
 
spu_maexp_memren,
 
spu_maaddr_nooddwr_on_leneq1,
 
spu_mared_not_idle,
spu_mamul_oprnd2_bypass,
 
spu_madp_perr,
 
ma_ctl_reg_data,
 
ifu_spu_trap_ack,
 
 
spu_mactl_rsrv_data_e,
 
 
 
spu_maaddr_len_cntr,
 
 
spu_wen_ma_unc_err,
spu_wen_ma_cor_err,
 
ifu_spu_nceen,
 
lsu_spu_ldst_ack,
mux_drive_disable,
 
 
se,
grst_l,
arst_l,
rclk);
 
// ---------------------------------------------
input grst_l;
input arst_l;
input rclk;
input se;
 
 
input spu_mald_memwen;
input spu_mamul_memwen;
input spu_mamul_memren;
input spu_maaeqb_memwen;
input spu_maaeqb_memren;
 
input spu_maaddr_maaddr_0;
input  spu_maaddr_mpa_3;
 
input  spu_mared_memren;
input  spu_mared_memwen;
 
input  spu_mast_memren;
 
 
input lsu_spu_early_flush_g;
input tlu_spu_flush_w;
input ifu_spu_flush_w;
input ifu_spu_inst_vld_w;
input [7:0] lsu_spu_asi_state_e;
input ifu_lsu_ld_inst_e;
input ifu_lsu_st_inst_e;
input ifu_lsu_alt_space_e;
input [1:0] ifu_tlu_thrid_e;
input [7:0] exu_lsu_ldst_va_e;
 
input spu_mald_done_set;
input spu_mast_done_set;
input spu_mared_done_set;
input spu_maexp_done_set;
 
input spu_maexp_memren;
 
input spu_maaddr_nooddwr_on_leneq1;
 
input spu_mared_not_idle;
input spu_mamul_oprnd2_bypass;
 
input spu_madp_perr;
 
input [13:0] ma_ctl_reg_data;
 
input ifu_spu_trap_ack;
 
 
input [2:0] spu_mactl_rsrv_data_e;
 
 
 
input [3:0] lsu_spu_stb_empty;
 
input spu_mast_streq;
 
input [5:0] spu_maaddr_len_cntr;
 
 
 
input spu_wen_ma_unc_err;
input spu_wen_ma_cor_err;
 
 
input [3:0] ifu_spu_nceen;
 
input lsu_spu_ldst_ack;
input mux_drive_disable;
 
// ---------------------------------------------
 
output spu_mactl_iss_pulse;
 
output spu_mactl_mpa_wen;
output spu_mactl_maaddr_wen;
output spu_mactl_manp_wen;
 
output spu_mactl_ldop;
output spu_mactl_stop;
output spu_mactl_mulop;
output spu_mactl_redop;
output spu_mactl_expop;
 
output [2:0] spu_mactl_memmxsel_l;
 
output spu_mactl_memeve_wen;
output spu_mactl_memodd_wen;
 
output spu_mactl_mamem_ren;
output spu_mactl_mamem_wen;
 
output spu_mactl_iss_pulse_dly;
 
output [3:0] spu_mactl_ldxa_data_w_sel_l;
output spu_mactl_ldxa_data_w_select;
 
output spu_mactl_mpa_sel;
 
output spu_mactl_madp_parflop_wen;
 
output spu_lsu_ldxa_data_vld_w2;
output [1:0] spu_lsu_ldxa_tid_w2;
output spu_lsu_stxa_ack;
output [1:0] spu_lsu_stxa_ack_tid;
 
 
output [13:0] spu_mactl_ldxa_mactl_reg;
 
output spu_mactl_force_perr;
 
output spu_ifu_ttype_w2;
output spu_ifu_ttype_vld_w2;
output [1:0] spu_ifu_ttype_tid_w;
 
output spu_tlu_rsrv_illgl_m;
 
 
output spu_ifu_corr_err_w2;
output spu_ifu_unc_err_w;
output spu_lsu_unc_error_w;
 
output spu_ifu_mamem_err_w;
output spu_ifu_int_w2;
output spu_lsu_ldxa_illgl_va_w2;
 
output spu_mactl_streq;
 
output spu_mactl_ctl_reset;
output spu_mactl_mem_reset_l;
 
 
output spu_mactl_ma_kill_op;
 
output spu_mactl_stxa_force_abort;
 
output [5:0] spu_mactl_mactl_len;
 
output spu_mactl_uncerr_rst;
 
output spu_mactl_iss_pulse_pre;
 
output spu_mactl_pcx_wen;
output spu_mactl_pcx_7170_sel;
 
output spu_mactl_perr_set;
 
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
wire [1:0] spu_mactl_ldxa_tid_g2;
wire [1:0] spu_mactl_ldxa_tid_w;
wire spu_mactl_clr_busy_bit;
wire spu_mactl_busy_bit_wen,spu_mactl_busy_bit_wrdata;
 
wire clr_busy_bit_when_masync;
 
wire spu_mactl_mactl_wen;
wire ma_op_done;
wire spu_mactl_rsrv_done_set;
wire spu_mactl_rsrv_wrdetect_m;
wire spu_mactl_perr_set_int;
wire spu_mactl_disable_stxa_ack_g2;
wire wait_4stb_tobecome_empty;
wire waiting_4stb_tobecome_empty;
wire spu_lsu_stxa_ack_q_buf;
 
wire wait4_trap_ack_set;
 
wire spu_mactl_nceen_4int;
 
wire spu_ifu_mamem_unc_w2;
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
/*
dffrl_async ma_mem_rst (.din (grst_l),
                        .q   (spu_mactl_mem_reset_l),
                        .clk (rclk),
                        .rst_l (arst_l), .se(se), .si(), .so());
*/
 
wire spu_mactl_ctl_rst_l;
dffrl_async ma_enc_rst (.din (grst_l),
                        .q   (spu_mactl_ctl_rst_l),
                        .clk (rclk),
                        .rst_l (arst_l), .se(se), .si(), .so());
 
 
 
wire spu_mactl_ctl_rst_local = ~spu_mactl_ctl_rst_l;
 
assign spu_mactl_ctl_reset = ~spu_mactl_ctl_rst_l;
 
assign spu_mactl_mem_reset_l = ~spu_mactl_ctl_rst_local;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
wire spu_mactl_stxa_2ctl_reg;
wire stxa_2ctl_reg = spu_mactl_stxa_2ctl_reg;
wire ma_op_complete, spu_mactl_done;
wire ma_op_complete_mask;
wire [1:0] spu_thrid_m,spu_thrid_g;
wire [1:0] spu_thrid_g2;
// -----------------------------------------------------------------
// -----------------------------------------------------------------
// -----------------------------------------------------------------
 
wire wait4_trap_ack_stxa2ctl = wait4_trap_ack_set & stxa_2ctl_reg;
 
// -----------------------------------------------------------------
// -----------------------------------------------------------------
// -----------------------------------------------------------------
// -----------------------------------------------------------------
wire  state_reset = spu_mactl_ctl_rst_local | spu_mactl_done ;
// -------------------------------------------------------------------------
 
/*************
state
-----
00	idle
01	operation inprogress
10	wait state
11	abort
**************/
dff_s    #(1) state_00_ff (
        .din(nxt_state_00) ,
        .q(cur_state_00),
        .clk (rclk), .se(se), .si(), .so());
 
dffr_s  #(1) state_01_ff (
        .din(nxt_state_01) ,
        .q(cur_state_01),
        .rst(state_reset), .clk (rclk), .se(se), .si(), .so());
 
dffr_s  #(1) state_10_ff (
        .din(nxt_state_10) ,
        .q(cur_state_10),
        .rst(state_reset), .clk (rclk), .se(se), .si(), .so());
 
dffr_s  #(1) state_11_ff (
        .din(nxt_state_11) ,
        .q(cur_state_11),
        .rst(state_reset), .clk (rclk), .se(se), .si(), .so());
// -------------------------------------------------------------------------
// transition to 00 state.
 
assign spu_mactl_done = cur_state_01 & ~stxa_2ctl_reg & ma_op_complete_mask;
 
assign  nxt_state_00 = (
                         state_reset | spu_mactl_done |
                         (cur_state_00 & ~stxa_2ctl_reg ));
 
// -------------------------------------------------------------------------
// transition to 01 state.
 
wire tr2state01_frm_state00 = cur_state_00 & stxa_2ctl_reg & ~wait_4stb_tobecome_empty &
								~wait4_trap_ack_stxa2ctl; 
wire tr2state01_frm_state10 = cur_state_10 & ~(stxa_2ctl_reg | waiting_4stb_tobecome_empty |
								wait4_trap_ack_set); 
 
assign  nxt_state_01 = (
			 tr2state01_frm_state00 |
			 tr2state01_frm_state10 |
                         (cur_state_01 & ~stxa_2ctl_reg & ~ma_op_complete_mask));
 
// -------------------------------------------------------------------------
// transition to 10 state.
 
wire tr2state10_frm_state11 = cur_state_11 & ~stxa_2ctl_reg & ma_op_complete_mask; 
wire tr2state10_frm_state10 = cur_state_10 & (stxa_2ctl_reg | waiting_4stb_tobecome_empty |
								wait4_trap_ack_set); 
wire tr2state10_frm_state00 = cur_state_00 & (wait_4stb_tobecome_empty | wait4_trap_ack_stxa2ctl); 
 
assign  nxt_state_10 = (
                         tr2state10_frm_state00 | tr2state10_frm_state11 | tr2state10_frm_state10 );
 
// -------------------------------------------------------------------------
// transition to 11 state.
 
wire tr2state11_frm_state01 = cur_state_01 & stxa_2ctl_reg; 
wire tr2state11_frm_state11 = cur_state_11 & (stxa_2ctl_reg | ~ma_op_complete_mask); 
 
assign  nxt_state_11 = (
                         tr2state11_frm_state11 | tr2state11_frm_state01 );
 
 
// -------------------------------------------------------------------------
 
assign spu_mactl_mactl_wen = tr2state01_frm_state00 | tr2state01_frm_state10;
 
wire spu_mactl_mactl_iss_mxsel = tr2state01_frm_state00;
wire spu_mactl_mactl_wen_a_reg = stxa_2ctl_reg;
 
 
wire tr2state01_frm_state00_q,tr2state01_frm_state00_qq;
dff_s  #(2) tr2state01_frm_state00_dly_ff (
        .din({tr2state01_frm_state00,tr2state01_frm_state00_q}) ,
        .q({tr2state01_frm_state00_q,tr2state01_frm_state00_qq}),
        .clk (rclk), .se(se), .si(), .so());
 
wire tr2state01_frm_state10_q,tr2state01_frm_state10_qq;
dff_s  #(2) tr2state01_frm_state10_dly_ff (
        .din({tr2state01_frm_state10,tr2state01_frm_state10_q}) ,
        .q({tr2state01_frm_state10_q,tr2state01_frm_state10_qq}),
        .clk (rclk), .se(se), .si(), .so());
 
// since there is a 2 cycle delay between stxa to ctlreg and issue signal getting
// asserted and clear of all *_done_set signals. Need to mask out the qualification
// with ma_complete for these 2 cycles.
assign ma_op_complete_mask = ma_op_complete & ~(tr2state01_frm_state00_q |
				tr2state01_frm_state00_qq) & ~(tr2state01_frm_state10_q |
                                tr2state01_frm_state10_qq);
 
assign spu_mactl_stxa_force_abort = cur_state_11;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// 				CTL REG
// -------------------------------------------------------------------------
wire [13:0] spu_mactl_mactl_reg;
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
wire [13:0] spu_mactl_young_ctlreg_data;
wire [13:0] spu_mactl_ctlreg_data_mxout;
// wire [1:0] old_ctlreg_issue_tid;
wire [1:0] young_ctlreg_issue_tid;
wire [1:0] ctlreg_tid_4cmp_2ldxa_tid;
wire ldxa_tid_match_ctlreg_tid_g2;
 
dffre_s  #(16) young_ctl_reg_ff (
        .din({spu_thrid_g2[1:0], ma_ctl_reg_data[13:0]}) ,
        .q({young_ctlreg_issue_tid[1:0],spu_mactl_young_ctlreg_data[13:0]}),
        .en(spu_mactl_mactl_wen_a_reg),
        .rst(spu_mactl_ctl_rst_local), .clk (rclk), .se(se), .si(), .so());
 
 
assign spu_mactl_ctlreg_data_mxout[13:0] = spu_mactl_mactl_iss_mxsel ? 
						 ma_ctl_reg_data[13:0] :
						 spu_mactl_young_ctlreg_data[13:0];
 
assign spu_mactl_ldxa_mactl_reg[13:0] = (cur_state_01 | cur_state_00) ? spu_mactl_mactl_reg[13:0] :
							spu_mactl_young_ctlreg_data[13:0];
 
assign ctlreg_tid_4cmp_2ldxa_tid[1:0] = (cur_state_01 | cur_state_00) ? spu_mactl_mactl_reg[12:11] :
							spu_mactl_young_ctlreg_data[12:11];
 
/*
replaced this with following since an ldxatosync followed and stxa2ctl was getting the incoorect timing
for compare of tids
 
assign ldxa_tid_match_ctlreg_tid_g = (ctlreg_tid_4cmp_2ldxa_tid[1:0] == spu_thrid_g[1:0]);
 
dff_s #(1) ldxa_tid_match_ctl_reg_tid_ff (
        .din(ldxa_tid_match_ctlreg_tid_g) ,
        .q(ldxa_tid_match_ctlreg_tid_g2),
        .clk (rclk), .se(se), .si(), .so()); 
*/
 
assign ldxa_tid_match_ctlreg_tid_g2 = (ctlreg_tid_4cmp_2ldxa_tid[1:0] == spu_thrid_g2[1:0]);
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
wire spu_mactl_busy_bit;
mux2ds #(1) busy_bit_mx (
        .in0    (spu_mactl_busy_bit_wrdata),
        .in1    (spu_mactl_ctlreg_data_mxout[10]),
        .sel0    (spu_mactl_busy_bit_wen),
        .sel1    (~spu_mactl_busy_bit_wen),
        .dout   (spu_mactl_busy_bit));
 
dffre_s  #(1) ctl_reg_busybit_ff (
        .din(spu_mactl_busy_bit ) ,
        .q(spu_mactl_mactl_reg[10]),
        .en(spu_mactl_busy_bit_wen),
        .rst(spu_mactl_ctl_rst_local|spu_mactl_clr_busy_bit), .clk (rclk), .se(se), .si(), .so());
 
///wire ma_is_busy = spu_mactl_mactl_reg[10];
 
 
/*
dffre_s  #(9) mactl_reg_ff (
        .din({spu_mactl_ctlreg_data_mxout[15:11],spu_mactl_ctlreg_data_mxout[9:6]}) ,
        .q({old_ctlreg_issue_tid[1:0], spu_mactl_mactl_reg[13:11],spu_mactl_mactl_reg[9:6]}),
        .en(spu_mactl_mactl_wen),
        .rst(spu_mactl_ctl_rst_local), .clk (rclk), .se(se), .si(), .so());
*/
 
dffre_s  #(7) mactl_reg_ff (
        .din({spu_mactl_ctlreg_data_mxout[13:11],spu_mactl_ctlreg_data_mxout[9:6]}) ,
        .q({spu_mactl_mactl_reg[13:11],spu_mactl_mactl_reg[9:6]}),
        .en(spu_mactl_mactl_wen),
        .rst(spu_mactl_ctl_rst_local), .clk (rclk), .se(se), .si(), .so());
 
 
wire spu_mactl_int_set = spu_mactl_mactl_reg[9];
 
 
 
/////////   NEED TO DO LEN UPDATE AT THE END also
 
wire [5:0] spu_mactl_len_cntr_mx;
dffre_s  #(6) mactl_reg_len_ff (
        .din(spu_mactl_len_cntr_mx[5:0]) ,
        .q(spu_mactl_mactl_reg[5:0]),
        .en(spu_mactl_mactl_wen | spu_mast_streq),
        .rst(spu_mactl_ctl_rst_local), .clk (rclk), .se(se), .si(), .so());
 
 
assign spu_mactl_mactl_len = spu_mactl_mactl_reg[5:0];
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// LEN field update
 
 
assign spu_mactl_len_cntr_mx[5:0] = (spu_maaddr_len_cntr[5:0] & {6{~spu_mactl_mactl_wen}}) |
					(spu_mactl_ctlreg_data_mxout[5:0] & {6{spu_mactl_mactl_wen}}) ;
 
 
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// stb empty logic
 
wire allow_stxaack_waiting4trapack_pulse;
 
wire spu_thrid_decode_tid0 = ~spu_thrid_g2[1] & ~spu_thrid_g2[0];
wire spu_thrid_decode_tid1 = ~spu_thrid_g2[1] & spu_thrid_g2[0];
wire spu_thrid_decode_tid2 = spu_thrid_g2[1] & ~spu_thrid_g2[0];
wire spu_thrid_decode_tid3 = spu_thrid_g2[1] & spu_thrid_g2[0];
 
 
wire stb_isempty =
                                (lsu_spu_stb_empty[0] & spu_thrid_decode_tid0) |
                                (lsu_spu_stb_empty[1] & spu_thrid_decode_tid1) |
                                (lsu_spu_stb_empty[2] & spu_thrid_decode_tid2) |
                                (lsu_spu_stb_empty[3] & spu_thrid_decode_tid3) ;
 
 
wire wait_4stb_empty_wen = stxa_2ctl_reg & ~stb_isempty;
wire wait_4stb_empty_rst = (stxa_2ctl_reg & stb_isempty) | 
				tr2state01_frm_state10 |
				(allow_stxaack_waiting4trapack_pulse & ~wait_4stb_empty_wen) ;
 
assign spu_mactl_disable_stxa_ack_g2 = wait_4stb_empty_wen;
assign wait_4stb_tobecome_empty = wait_4stb_empty_wen;
 
wire waiting_4stb_empty_set;
dffre_s #(1) wait_4stb_empty_ff (
        .din(1'b1) ,
        .q(waiting_4stb_empty_set),
        .en(wait_4stb_empty_wen),
        .rst(spu_mactl_ctl_rst_local | wait_4stb_empty_rst), .clk (rclk), .se(se), .si(), .so()); 
 
wire young_thrid_decode_tid0 = ~young_ctlreg_issue_tid[1] & ~young_ctlreg_issue_tid[0];
wire young_thrid_decode_tid1 = ~young_ctlreg_issue_tid[1] & young_ctlreg_issue_tid[0];
wire young_thrid_decode_tid2 = young_ctlreg_issue_tid[1] & ~young_ctlreg_issue_tid[0];
wire young_thrid_decode_tid3 = young_ctlreg_issue_tid[1] & young_ctlreg_issue_tid[0];
 
wire stb_hasbecome_empty_while_instate10 =
                                (lsu_spu_stb_empty[0] & young_thrid_decode_tid0) |
                                (lsu_spu_stb_empty[1] & young_thrid_decode_tid1) |
                                (lsu_spu_stb_empty[2] & young_thrid_decode_tid2) |
                                (lsu_spu_stb_empty[3] & young_thrid_decode_tid3) ;
 
assign waiting_4stb_tobecome_empty  = (~stb_hasbecome_empty_while_instate10 & waiting_4stb_empty_set) | 
										wait_4stb_empty_wen;
 
wire allow_stxa_ack_while_instate10 = 
	//(waiting_4stb_empty_set & wait_4stb_empty_wen & cur_state_10) | // when in state10 & waiting 
	//(waiting_4stb_empty_set & wait_4stb_empty_wen ) | // when in state10 & waiting 
	(waiting_4stb_empty_set & stxa_2ctl_reg ) | // when in state10 & waiting 
									// 4stb_empty & there is stxa_2ctlreg.
	(waiting_4stb_empty_set & tr2state01_frm_state10 & stb_hasbecome_empty_while_instate10) | // when in state10 & 
									// waiting 4stb_empty and stb becomes empty. 
	allow_stxaack_waiting4trapack_pulse;
 
 
 
wire delayed_allow_stxa_ack;
wire delayed_allow_stxa_ack_pre = (stxa_2ctl_reg & stb_isempty & waiting_4stb_empty_set) |
					(spu_lsu_stxa_ack_q_buf & stxa_2ctl_reg & stb_isempty);//this is to resolve
									//b-b-b stxa's
 
wire waiting_4stb_empty_set_dly;
dff_s #(1) waiting_4stb_empty_set_dly_ff (
        .din(waiting_4stb_empty_set) ,
        .q(waiting_4stb_empty_set_dly),
        .clk (rclk), .se(se), .si(), .so());
 
wire waiting_4stb_empty_set_dly2;
dff_s #(1) waiting_4stb_empty_set_dly2_ff (
        .din(waiting_4stb_empty_set_dly) ,
        .q(waiting_4stb_empty_set_dly2),
        .clk (rclk), .se(se), .si(), .so());
 
 
wire delayed_allow_stxa_ack_pre_qual = delayed_allow_stxa_ack_pre & (waiting_4stb_empty_set |
						waiting_4stb_empty_set_dly | waiting_4stb_empty_set_dly2);
 
dffr_s #(1) delayed_allow_stxa_ack_pre_ff (
        .din(delayed_allow_stxa_ack_pre_qual) ,
        .q(delayed_allow_stxa_ack),
        .rst(spu_mactl_ctl_rst_local), .clk (rclk), .se(se), .si(), .so());
 
// ################################################################################ 
// ECO bug5326.
// this is related to stxa not getting acked when in state 10 and stb becomes empty and wait4_trap_ack is
// asserted and becaues of this tr2state01_frm_state10 does not occur and as a result no ack is sent out
// and when stb becomes empty(wait4_trap_ack is still waiting for ack) still no ack and stxa hangs.
 
wire  allow_stxaack_waiting4trapack = waiting_4stb_empty_set & stb_hasbecome_empty_while_instate10 & 
						cur_state_10 & wait4_trap_ack_set;
 
wire allow_stxaack_waiting4trapack_q;
dff_s  #(1) allow_stxaack_waiting4trapack_ff (
        .din(allow_stxaack_waiting4trapack) ,
        .q(allow_stxaack_waiting4trapack_q),
        .clk (rclk), .se(se), .si(), .so()); 
 
assign allow_stxaack_waiting4trapack_pulse = ~allow_stxaack_waiting4trapack_q & allow_stxaack_waiting4trapack;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
/*
dffr_s  #(1) spu_mactl_streq_ff (
        .din(spu_mast_streq) ,
        .q(spu_mactl_streq),
        .rst(lsu_spu_ldst_ack),
        .clk (rclk), .se(se), .si(), .so()); 
*/
 
wire spu_mactl_streq_set;
dffre_s  #(1) spu_mactl_streq_ff (
        .din(1'b1) ,
        .q(spu_mactl_streq_set),
        .en(spu_mast_streq),
        .rst(spu_mactl_ctl_rst_local | lsu_spu_ldst_ack), .clk (rclk), .se(se), .si(), .so());
 
//assign spu_mactl_streq = spu_mast_streq | spu_mactl_streq_set;
assign spu_mactl_streq = spu_mactl_streq_set ;
 
 
wire spu_mactl_pcx_7170_sel_pre = spu_mast_streq | spu_mactl_ldop;
 
dff_s  #(1) spu_mactl_pcx_7170_sel_ff (
        .din(spu_mactl_pcx_7170_sel_pre) ,
        .q(spu_mactl_pcx_7170_sel),
        .clk (rclk), .se(se), .si(), .so());
 
dff_s  #(1) spu_mactl_pcx_wen_ff (
        .din(spu_mactl_pcx_7170_sel_pre) ,
        .q(spu_mactl_pcx_wen),
        .clk (rclk), .se(se), .si(), .so());
 
/*
assign spu_mactl_pcx_7170_sel = spu_mast_streq_q | spu_mactl_ldop;
assign spu_mactl_pcx_wen = spu_mactl_pcx_7170_sel;
*/
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// SETTING THE BUSY BIT.
// -------------------------------------------------------------------------
// when spu_mactl_iss_pulse_dly is set busy_bit is set and when operation
// is done it is cleared.
 
 
assign spu_mactl_busy_bit_wen = spu_mactl_iss_pulse_dly |  
                                        spu_mactl_mactl_wen;
 
assign spu_mactl_busy_bit_wrdata = spu_mactl_iss_pulse_dly;
 
 
 
wire clr_busy_bit_when_maint = spu_mactl_int_set & ifu_spu_trap_ack;
//wire clr_busy_bit_when_maint = spu_mactl_int_set & 1'b0;
 
//wire spu_mactl_clr_all_done_set = clr_busy_bit_when_maint;
 
assign spu_mactl_clr_busy_bit = clr_busy_bit_when_masync | clr_busy_bit_when_maint;
 
 
/******************************************************************************/
// completion by interrupt.
// ----------------------------------------
 
wire done_set_pulse_q;
dff_s  #(1) doneset_pulse_ff (
        .din(ma_op_done) ,
        .q(done_set_pulse_q),
        .clk (rclk), .se(se), .si(), .so()); 
 
 
wire spu_mactl_ttype_vld = (~done_set_pulse_q & ma_op_done & spu_mactl_int_set) &
					(cur_state_00 | cur_state_01) & ~stxa_2ctl_reg ; 
									// prevent from sending completion
									// interrupt when in abort mode.
 
wire spu_mactl_ttype_vld_dly;
dff_s    #(1) ma_ttype_vld_ff (
        .din(spu_mactl_ttype_vld) ,
        .q(spu_mactl_ttype_vld_dly),
        .clk (rclk), .se(se), .si(), .so());
 
// ----------------------------------------
// ----ttype logic, 1 => 74(ma), 0 => 70(enc); enc has higher priority.
wire spu_mactl_ttype;
assign spu_mactl_ttype = 1'b1; 
 
// ----------------------------------------
// ----tid logic
assign spu_ifu_ttype_tid_w = spu_mactl_int_set ? spu_mactl_mactl_reg[12:11] :
						spu_mactl_ldxa_tid_g2[1:0];// changed to _g2 since
										//ifu_errctl flops it as well.
 
// ----------------------------------------
dff_s    #(2) spu_ifu_ttype_ff (
        .din({spu_mactl_ttype,spu_mactl_ttype_vld_dly}) ,
        .q({spu_ifu_ttype_w2,spu_ifu_ttype_vld_w2}),
        .clk (rclk), .se(se), .si(), .so());
 
// ----------------------------------------
 
wire ctl_tid_decode0 = ~spu_mactl_mactl_reg[12] & ~spu_mactl_mactl_reg[11];
wire ctl_tid_decode1 = ~spu_mactl_mactl_reg[12] & spu_mactl_mactl_reg[11];
wire ctl_tid_decode2 = spu_mactl_mactl_reg[12] & ~spu_mactl_mactl_reg[11];
wire ctl_tid_decode3 = spu_mactl_mactl_reg[12] & spu_mactl_mactl_reg[11];
 
//wire [3:0] ifu_spu_nceen_q;
assign spu_mactl_nceen_4int =
                                (ifu_spu_nceen[0] & ctl_tid_decode0) |
                                (ifu_spu_nceen[1] & ctl_tid_decode1) |
                                (ifu_spu_nceen[2] & ctl_tid_decode2) |
                                (ifu_spu_nceen[3] & ctl_tid_decode3) ;
 
// ----------------------------------------
 
wire wait4_trap_ack_rst = spu_ifu_mamem_unc_w2 & spu_mactl_nceen_4int ;
 
dffre_s  #(1) wait4_trap_ack_ff (
        .din(1'b1) ,
        .q(wait4_trap_ack_set),
        .en(spu_mactl_ttype_vld),
        .rst(spu_mactl_ctl_rst_local | ifu_spu_trap_ack | wait4_trap_ack_rst), .clk (rclk), .se(se), .si(), .so());
 
 
// -------------------------------------------------------------------------
// ***************** VA COMPARES ********************
// -------------------------------------------------------------------------
wire [7:0] spu_ldst_va_m,spu_ldst_va_m_buf,spu_ldst_va_g;
wire spu_mactl_mactl_va_vld_g;
 
wire spu_mactl_masync_va_vld_g 	= (spu_ldst_va_g[7:0] == 8'ha0);
wire spu_mactl_mpa_va_vld_g 	= (spu_ldst_va_g[7:0] == 8'h88);
wire spu_mactl_maaddr_va_vld_g 	= (spu_ldst_va_g[7:0] == 8'h90);
wire spu_mactl_manp_va_vld_g 	= (spu_ldst_va_g[7:0] == 8'h98);
 
wire spu_mactl_mactl_va_vld_m 	= (spu_ldst_va_m[7:0] == 8'h80);
 
dff_s  #(1) spu_mactl_mactl_va_vld_m_ff (
        .din(spu_mactl_mactl_va_vld_m) ,
        .q(spu_mactl_mactl_va_vld_g),
        .clk (rclk), .se(se), .si(), .so());
 
 
wire spu_mactl_ma_va_vld_g = spu_mactl_masync_va_vld_g | spu_mactl_mpa_va_vld_g |
					spu_mactl_maaddr_va_vld_g | spu_mactl_manp_va_vld_g |
					spu_mactl_mactl_va_vld_g;
 
wire spu_mactl_illgl_va_g = ~spu_mactl_ma_va_vld_g ;
 
 
wire spu_mactl_masync_va_vld_g2, spu_mactl_mpa_va_vld_g2, spu_mactl_maaddr_va_vld_g2,
                        spu_mactl_manp_va_vld_g2, spu_mactl_mactl_va_vld_g2, spu_mactl_illgl_va_g2;
 
dff_s  #(6) mactl_va_vld_g2_ff (
        .din({spu_mactl_masync_va_vld_g, spu_mactl_mpa_va_vld_g, spu_mactl_maaddr_va_vld_g,
			spu_mactl_manp_va_vld_g, spu_mactl_mactl_va_vld_g, spu_mactl_illgl_va_g}) ,
        .q({spu_mactl_masync_va_vld_g2, spu_mactl_mpa_va_vld_g2, spu_mactl_maaddr_va_vld_g2,
                        spu_mactl_manp_va_vld_g2, spu_mactl_mactl_va_vld_g2, spu_mactl_illgl_va_g2}),
        .clk (rclk), .se(se), .si(), .so());
 
 
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
wire spu_ld_inst_m,spu_st_inst_m,spu_alt_space_m;
wire spu_mactl_asi_is_40_m;
wire spu_mactl_asi_is_40_m_buf;
wire spu_mactl_asi_is_40_e;
 
dff_s  #(13) ifu_spu_pipe_ff (
        .din({ifu_lsu_ld_inst_e,ifu_lsu_st_inst_e,ifu_lsu_alt_space_e,
              ifu_tlu_thrid_e[1:0],exu_lsu_ldst_va_e[7:0]}) ,
        .q({spu_ld_inst_m,spu_st_inst_m,spu_alt_space_m,
              spu_thrid_m[1:0],spu_ldst_va_m[7:0]}),
        .clk (rclk), .se(se), .si(), .so());
 
assign spu_ldst_va_m_buf = spu_ldst_va_m;
 
// asi addr = 80
 
wire spu_mactl_mactl_wen_m_prequal = spu_mactl_asi_is_40_m_buf & spu_alt_space_m & spu_st_inst_m ;
/*
wire spu_mactl_mactl_wen_m = spu_mactl_mactl_va_vld_m & spu_mactl_asi_is_40_m &
				spu_alt_space_m & spu_st_inst_m ;
*/
                                //ifu_tlu_inst_vld_m;
 
wire spu_mactl_mactl_wen_m = spu_mactl_mactl_va_vld_m & spu_mactl_mactl_wen_m_prequal ;
 
wire spu_mactl_mactl_wen_g;
dff_s  #(1) spu_mactl_mactl_ack_ff (
        .din(spu_mactl_mactl_wen_m) ,
        .q(spu_mactl_mactl_wen_g),
        .clk (rclk), .se(se), .si(), .so());
 
 
///wire spu_mactl_mactl_wen_busy_m = spu_mactl_mactl_wen_m & ~ma_is_busy;
// wire spu_mactl_mactl_wen_vld_m = spu_mactl_mactl_wen_busy_m & ifu_tlu_inst_vld_m;
 
/*
wire spu_mactl_mactl_wen_busy_g;
dff_s  #(1) spu_mactl_mactl_wen_busy_m_ff (
        .din(spu_mactl_mactl_wen_busy_m) ,
        .q(spu_mactl_mactl_wen_busy_g),
        .clk (rclk), .se(se), .si(), .so());
 
wire spu_mactl_mactl_wen_vld_g = spu_mactl_mactl_wen_busy_g & ifu_spu_inst_vld_w;
 
*/
 
 
wire spu_mactl_mactl_wen_vld_g = spu_mactl_mactl_wen_g & ifu_spu_inst_vld_w;
 
wire spu_mactl_mactl_wen_vld_g2;
dff_s  #(1) spu_mactl_mactl_wen_vld_g_ff (
        .din(spu_mactl_mactl_wen_vld_g) ,
        .q(spu_mactl_mactl_wen_vld_g2),
        .clk (rclk), .se(se), .si(), .so());
 
 
 
dff_s  #(10) spu_pipe_ff (
        .din({spu_thrid_m[1:0],spu_ldst_va_m_buf[7:0]}),
        .q({spu_thrid_g[1:0],spu_ldst_va_g[7:0]}),
        .clk (rclk), .se(se), .si(), .so());
 
 
dff_s  #(2) tid_g2_ff (
        .din(spu_thrid_g[1:0]) ,
        .q(spu_thrid_g2[1:0]),
        .clk (rclk), .se(se), .si(), .so());
 
/*
wire [7:0] spu_mactl_asi_state_m;
dff_s  #(8) spu_mactl_asi_state_ff (
        .din(lsu_spu_asi_state_e[7:0]) ,
        .q(spu_mactl_asi_state_m[7:0]),
        .clk (rclk), .se(se), .si(), .so());
*/
 
assign spu_mactl_asi_is_40_e = (lsu_spu_asi_state_e[7:0] == 8'h40);
 
dff_s  #(2) spu_mactl_asi_is_40_e_ff (
        .din({spu_mactl_asi_is_40_e, spu_mactl_asi_is_40_e}) ,
        .q({spu_mactl_asi_is_40_m, spu_mactl_asi_is_40_m_buf}),
        .clk (rclk), .se(se), .si(), .so());
 
wire spu_mactl_asi40_alt_st_m = spu_mactl_asi_is_40_m & spu_alt_space_m & spu_st_inst_m ; 
wire spu_mactl_asi40_alt_ld_m = spu_mactl_asi_is_40_m & spu_alt_space_m & spu_ld_inst_m ; 
 
// wire spu_mactl_asi40_alt_st_vld_m = spu_mactl_asi40_alt_st_m & ifu_tlu_inst_vld_m;
// wire spu_mactl_asi40_alt_ld_vld_m = spu_mactl_asi40_alt_ld_m & ifu_tlu_inst_vld_m;
 
 
wire spu_mactl_asi40_alt_st_g,spu_mactl_asi40_alt_ld_g;
dff_s  #(2) vld_ldst_alt_asi40_ff (
        .din({spu_mactl_asi40_alt_st_m,spu_mactl_asi40_alt_ld_m}) ,
        .q({spu_mactl_asi40_alt_st_g,spu_mactl_asi40_alt_ld_g}),
        .clk (rclk), .se(se), .si(), .so());
 
 
wire spu_mactl_asi40_alt_st_vld_g = spu_mactl_asi40_alt_st_g & ifu_spu_inst_vld_w;
wire spu_mactl_asi40_alt_ld_vld_g = spu_mactl_asi40_alt_ld_g & ifu_spu_inst_vld_w;
 
 
wire spu_mactl_asi40_alt_st_vld_g2,spu_mactl_asi40_alt_ld_vld_g2;
dff_s  #(2) vld_ldst_alt_asi40_g2_ff (
        .din({spu_mactl_asi40_alt_st_vld_g,spu_mactl_asi40_alt_ld_vld_g}) ,
        .q({spu_mactl_asi40_alt_st_vld_g2,spu_mactl_asi40_alt_ld_vld_g2}),
        .clk (rclk), .se(se), .si(), .so());
 
 
 
wire all_flush = lsu_spu_early_flush_g | tlu_spu_flush_w | ifu_spu_flush_w;
 
wire spu_mactl_flush_g2;
dff_s  #(1) flush_ff (
        .din(all_flush) ,
        .q(spu_mactl_flush_g2),
        .clk (rclk), .se(se), .si(), .so());
 
 
wire spu_mactl_st_asi_vld = spu_mactl_asi40_alt_st_vld_g2 & ~spu_mactl_flush_g2;
wire spu_mactl_ld_asi_vld = spu_mactl_asi40_alt_ld_vld_g2 & ~spu_mactl_flush_g2;
 
 
wire spu_mactl_st_asi_vld_local = spu_mactl_st_asi_vld;
wire spu_mactl_ld_asi_vld_local = spu_mactl_ld_asi_vld;
 
wire spu_mactl_illgl_va_vld_g2 = spu_mactl_illgl_va_g2 & spu_mactl_ld_asi_vld_local;
 
 
 
// -------------------------------------------------------------------------
// ******************* ST ASI ***********************
// -------------------------------------------------------------------------
// ST ASI decode and generate write enables.
 
// asi addr = 88
assign spu_mactl_mpa_wen = spu_mactl_mpa_va_vld_g2 & spu_mactl_st_asi_vld_local ; 
 
// asi addr = 90
assign spu_mactl_maaddr_wen = spu_mactl_maaddr_va_vld_g2 & spu_mactl_st_asi_vld_local ; 
 
// asi addr = 98
assign spu_mactl_manp_wen = spu_mactl_manp_va_vld_g2 & spu_mactl_st_asi_vld_local ; 
 
// asi addr = 80
assign spu_mactl_stxa_2ctl_reg = spu_mactl_mactl_wen_vld_g2 & ~spu_mactl_flush_g2 ;
 
 
 
// -------------------------------------------------------------------------
// STXA ACK 
// -------------------------------------------------------------------------
wire spu_lsu_stxa_ack_g2;
wire disable_stxa_ack_4b2b_same_tid;
 
wire spu_lsu_stxa_ack_g2_prequal = ( spu_mactl_stxa_2ctl_reg & ~spu_mactl_disable_stxa_ack_g2) |
				allow_stxa_ack_while_instate10 |
				delayed_allow_stxa_ack;
 
assign spu_lsu_stxa_ack_g2 = spu_lsu_stxa_ack_g2_prequal & ~disable_stxa_ack_4b2b_same_tid;
 
dff_s  #(1) stxa_ack_g2_ff (
        .din(spu_lsu_stxa_ack_g2) ,
        .q(spu_lsu_stxa_ack),
        .clk (rclk), .se(se), .si(), .so());
 
assign spu_lsu_stxa_ack_q_buf = spu_lsu_stxa_ack;
 
assign spu_lsu_stxa_ack_tid[1:0] =  (allow_stxa_ack_while_instate10 |
				     delayed_allow_stxa_ack) ? young_ctlreg_issue_tid[1:0] :
									spu_thrid_g2[1:0]; 
 
 
// following is to avoid the case when the logic generates a b2b stxa ack for the same tid.
wire [1:0] spu_lsu_stxa_ack_tid_g3;
dff_s  #(2) stxa_ack_tid_g2_ff (
        .din(spu_lsu_stxa_ack_tid[1:0]) ,
        .q(spu_lsu_stxa_ack_tid_g3[1:0]),
        .clk (rclk), .se(se), .si(), .so());
 
wire g2_g3_tids_match = (spu_lsu_stxa_ack_tid[1:0] == spu_lsu_stxa_ack_tid_g3[1:0]);
 
assign disable_stxa_ack_4b2b_same_tid = spu_lsu_stxa_ack & g2_g3_tids_match;
 
// -------------------------------------------------------------------------
// ******************* LD ASI ***********************
// -------------------------------------------------------------------------
// LD ASI decode and generate write enables.
wire masync_set;
wire spu_mactl_masync_ldxa;
wire spu_mactl_masync_ldxa_sel;
wire spu_mactl_masync_ldxa_sel_pre;
// asi addr = A0
 
assign spu_mactl_masync_ldxa = spu_mactl_masync_va_vld_g2 & spu_mactl_ld_asi_vld_local;
 
//wire spu_mactl_masync_ldxa_qual = spu_mactl_masync_ldxa & ~masync_set;
wire spu_mactl_masync_ldxa_qual = spu_mactl_masync_ldxa & ldxa_tid_match_ctlreg_tid_g2;
 
wire spu_mactl_masync_ldxa_rst = spu_mactl_ctl_rst_local | spu_mactl_masync_ldxa_sel_pre;
 
wire [1:0] masync_tid;
 
dffre_s  #(3) masync_ff (
        .din({1'b1,spu_thrid_g2[1:0]}) ,
        .q({masync_set,masync_tid[1:0]}),
        .en(spu_mactl_masync_ldxa_qual),
        .rst(spu_mactl_masync_ldxa_rst), .clk (rclk), .se(se), .si(), .so());
 
//wire multi_masync_ldxa_sel = masync_set & spu_mactl_masync_ldxa;
//&&&&&&&&&&&&&&&&&&&&&
// following should signal to lsu spu_lsu_ldxa_data_vld and also spu_lsu_illgl_va.
//&&&&&&&&&&&&&&&&&&&&&
 
wire ldxa_2masync_tid_notmatch_ctlreg_tid = ~ldxa_tid_match_ctlreg_tid_g2 & spu_mactl_masync_ldxa;
 
 
wire spu_mactl_rst_done_set;
dffre_s #(1) spu_mactl_rst_done_ff (
        .din(1'b1) ,
        .q(spu_mactl_rst_done_set),
        .en(spu_mactl_ctl_rst_local),
        .rst(spu_mactl_iss_pulse_dly), .clk (rclk), .se(se), .si(), .so()); 
 
 
assign ma_op_done = spu_mald_done_set | spu_mared_done_set | spu_mast_done_set |
			spu_maexp_done_set | spu_mactl_rsrv_done_set | spu_mactl_rst_done_set;
 
assign ma_op_complete = spu_mald_done_set | spu_mared_done_set | spu_mast_done_set |
				spu_maexp_done_set;
 
 
//&&&&&&&&&&&&&&&&&&&&&
// mask(or delay) ma_op_done if ldxa to mpa_maaddr_manp_mactl register's is in progress to avoid conflicts
// with masync response when operation completes/aborts.
//&&&&&&&&&&&&&&&&&&&&&
 
 
wire spu_mactl_mask_done_set_4abort = cur_state_11 | cur_state_10 | tr2state01_frm_state10_q |
									tr2state01_frm_state10_qq;
 
 
 
wire spu_mactl_ldxa_mpa_maaddr_manp_mactl;
 
wire spu_mactl_masync_ldxa_set = ma_op_done & masync_set & ~spu_mactl_ldxa_mpa_maaddr_manp_mactl &
							~spu_mactl_masync_ldxa & // this is when ldxa to masync and
										// compleion occur at same time
							~spu_mactl_mask_done_set_4abort; 
 
wire masync_pulse_q;
 
dff_s  #(1) masync_pulse_ff (
	.din(spu_mactl_masync_ldxa_set) ,
	.q(masync_pulse_q),
	.clk (rclk), .se(se), .si(), .so());
 
 
//&&&&&&&&&&&&&&&&&&&&&
// following _pre signal is to signal an operation completed normally or was aborted.
//&&&&&&&&&&&&&&&&&&&&&
 
assign spu_mactl_masync_ldxa_sel_pre = (~masync_pulse_q & spu_mactl_masync_ldxa_set) |
					(masync_set & stxa_2ctl_reg); //this unblocks ldxa to sync reg since
									// this is an abort
 
assign spu_mactl_masync_ldxa_sel = spu_mactl_masync_ldxa_sel_pre | ldxa_2masync_tid_notmatch_ctlreg_tid;
 
//&&&&&&&&&&&&&&&&&&&&&
// mask out clearing the busy bit when another stxa is aborting the older operation. Since the timing
// of setting the busy bit is earlier than clearing it. So in this case the busy bit set for younger
// operation will be cleared when ldxa to sync is reponded as a result of the abort. And we want to avoid that.
//&&&&&&&&&&&&&&&&&&&&&
 
assign clr_busy_bit_when_masync = spu_mactl_masync_ldxa_sel_pre & ~(masync_set & stxa_2ctl_reg);
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// asi addr = 88
wire spu_mactl_mpa_ldxa_g2 = spu_mactl_mpa_va_vld_g2 & spu_mactl_ld_asi_vld_local ; 
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// asi addr = 90
wire spu_mactl_maaddr_ldxa_g2 = spu_mactl_maaddr_va_vld_g2 & spu_mactl_ld_asi_vld_local ; 
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// asi addr = 98
wire spu_mactl_manp_ldxa_g2 = spu_mactl_manp_va_vld_g2 & spu_mactl_ld_asi_vld_local ; 
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// asi addr = 80
wire spu_mactl_mactl_ldxa_g2 = spu_mactl_mactl_va_vld_g2 & spu_mactl_ld_asi_vld_local ; 
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
assign spu_mactl_ldxa_tid_g2[1:0] = (({2{spu_mactl_mpa_ldxa_g2}} & spu_thrid_g2[1:0]) |
                                    ({2{spu_mactl_maaddr_ldxa_g2}} & spu_thrid_g2[1:0]) |
                                    ({2{spu_mactl_manp_ldxa_g2}} & spu_thrid_g2[1:0]) |
                                    ({2{spu_mactl_mactl_ldxa_g2}} & spu_thrid_g2[1:0]) |
                                    ({2{spu_mactl_masync_ldxa_sel}} & masync_tid[1:0]) );
*/
 
 
assign spu_mactl_ldxa_tid_g2[1:0] = spu_mactl_masync_ldxa_sel_pre ? masync_tid[1:0] :
									spu_thrid_g2[1:0];
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
assign spu_mactl_ldxa_mpa_maaddr_manp_mactl = spu_mactl_mpa_ldxa_g2 | spu_mactl_maaddr_ldxa_g2 |
						spu_mactl_manp_ldxa_g2 | spu_mactl_mactl_ldxa_g2;
 
wire spu_mactl_ldxa_data_vld_g2 = 	spu_mactl_ldxa_mpa_maaddr_manp_mactl |
					spu_mactl_illgl_va_vld_g2 |
					spu_mactl_masync_ldxa_sel;
 
// any ldxa to masync reg that its tid does not match tid of ctlreg should generate an
// illgl_va to lsu, so lsu silently drops it(no writes to the reg file).
 
wire illgl_va_vld_or_drop_ldxa2masync = spu_mactl_illgl_va_vld_g2 | ldxa_2masync_tid_notmatch_ctlreg_tid |
						(masync_set & stxa_2ctl_reg);
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
// fix for bug 4918, when ldxa to tid3 which causes illl_va and masyc completion to another tid 
// that causes unc_err. both of these happen at the same time, need to delay unc_err.
 
wire spu_mactl_ldxa_data_vld_qual = spu_mactl_masync_ldxa_sel | spu_mactl_ldxa_mpa_maaddr_manp_mactl; 
 
wire spu_mactl_illgl_va_vld_w;
wire spu_mactl_ldxa_data_vld_qual_w;
dff_s #(1) spu_mactl_ldxa_data_vld_qual_ff (
        .din(spu_mactl_ldxa_data_vld_qual) ,
        .q(spu_mactl_ldxa_data_vld_qual_w),
        .clk (rclk), .se(se), .si(), .so());
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
wire spu_mactl_ldxa_data_vld_w;
dff_s  #(4) ldxa_tid_vld_ff (
        //.din({spu_mactl_ldxa_tid_g2[1:0],spu_mactl_ldxa_data_vld_g2, spu_mactl_illgl_va_vld_g2}) ,
 
        .din({spu_mactl_ldxa_tid_g2[1:0],spu_mactl_ldxa_data_vld_g2, illgl_va_vld_or_drop_ldxa2masync}) ,
        .q({spu_mactl_ldxa_tid_w[1:0],spu_mactl_ldxa_data_vld_w, spu_mactl_illgl_va_vld_w}),
        .clk (rclk), .se(se), .si(), .so());
 
 
assign spu_lsu_ldxa_data_vld_w2 = spu_mactl_ldxa_data_vld_w ;
assign spu_lsu_ldxa_tid_w2[1:0] = spu_mactl_ldxa_tid_w[1:0] ;
 
wire spu_mactl_perr_rst;
assign spu_lsu_ldxa_illgl_va_w2 = spu_mactl_illgl_va_vld_w & ~spu_lsu_unc_error_w;
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
wire [3:0] spu_mactl_ldxa_data_g2_sel;
wire spu_mactl_ldxa_data_g2_select;
 
/******				*************
assign spu_mactl_ldxa_data_g2_sel[3:0] = {spu_mactl_mactl_ldxa_g2,
					 spu_mactl_manp_ldxa_g2,
					 spu_mactl_maaddr_ldxa_g2,
					 spu_mactl_mpa_ldxa_g2};
*******				*************/
 
 
assign spu_mactl_ldxa_data_g2_sel[0] = spu_mactl_mpa_ldxa_g2;
assign spu_mactl_ldxa_data_g2_sel[1] = ~spu_mactl_mpa_ldxa_g2 & spu_mactl_maaddr_ldxa_g2;
assign spu_mactl_ldxa_data_g2_sel[2] = ~spu_mactl_mpa_ldxa_g2 & ~spu_mactl_maaddr_ldxa_g2 &
                                                spu_mactl_manp_ldxa_g2;
assign spu_mactl_ldxa_data_g2_sel[3] = ~spu_mactl_mpa_ldxa_g2 & ~spu_mactl_maaddr_ldxa_g2 &
                                                ~spu_mactl_manp_ldxa_g2;
 
 
 
 
assign spu_mactl_ldxa_data_g2_select = ~(spu_mactl_mactl_ldxa_g2 |
                                         spu_mactl_manp_ldxa_g2 |
                                         spu_mactl_maaddr_ldxa_g2 |
                                         spu_mactl_mpa_ldxa_g2);
 
wire [3:0] spu_mactl_ldxa_data_w_sel;
dff_s  #(5) ldxa_data_sel_ff (
        .din({spu_mactl_ldxa_data_g2_sel[3:0],spu_mactl_ldxa_data_g2_select}) ,
        .q({spu_mactl_ldxa_data_w_sel[3:0],spu_mactl_ldxa_data_w_select}),
        .clk (rclk), .se(se), .si(), .so());
 
 
wire [3:0] spu_mactl_ldxa_data_w_sel_s;
assign spu_mactl_ldxa_data_w_sel_s[0] = spu_mactl_ldxa_data_w_sel[0] | mux_drive_disable;
assign spu_mactl_ldxa_data_w_sel_s[1] = spu_mactl_ldxa_data_w_sel[1] & ~mux_drive_disable;
assign spu_mactl_ldxa_data_w_sel_s[2] = spu_mactl_ldxa_data_w_sel[2] & ~mux_drive_disable;
assign spu_mactl_ldxa_data_w_sel_s[3] = spu_mactl_ldxa_data_w_sel[3] & ~mux_drive_disable;
 
 
assign spu_mactl_ldxa_data_w_sel_l = ~spu_mactl_ldxa_data_w_sel_s;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// reserve bit write detect. Kill start signal(spu_encctl_iss_pulse_dly) and
// signal a completion signal.
// ---------------------------------------------------
 
wire [2:0] spu_mactl_op_field_e;
//wire [2:0] spu_mactl_op_field_m;
 
assign spu_mactl_op_field_e[2:0] = spu_mactl_rsrv_data_e[2:0];
 
wire spu_mactl_rsrv_wrdetect_e = spu_mactl_op_field_e[2] & ~(~(spu_mactl_op_field_e[1]|spu_mactl_op_field_e[0]));
 
wire spu_mactl_rsrv_wrdetect_noqual_m;
dff_s #(1) spu_mactl_rsrv_wrdetect_e_ff (
        .din(spu_mactl_rsrv_wrdetect_e) ,
        .q(spu_mactl_rsrv_wrdetect_noqual_m),
        .clk (rclk), .se(se), .si(), .so());
 
assign spu_mactl_rsrv_wrdetect_m = spu_mactl_rsrv_wrdetect_noqual_m & spu_mactl_mactl_wen_m;
 
/*
dffr_s #(3) rsrv_data_ff (
        .din(spu_mactl_rsrv_data_e[2:0]) ,
        .q(spu_mactl_op_field_m[2:0]),
        .rst(spu_mactl_ctl_rst_local), .clk (rclk), .se(se), .si(), .so());
 
 
assign spu_mactl_rsrv_wrdetect_m =
		spu_mactl_op_field_m[2] & ~(~(spu_mactl_op_field_m[1]|spu_mactl_op_field_m[0])) &
		spu_mactl_mactl_wen_m;
 
*/
 
wire spu_mactl_rsrv_done_wen; 
wire spu_mactl_rsrv_done_rst = spu_mactl_ctl_rst_local | spu_mactl_iss_pulse_dly;
 
dffre_s #(1) spu_mactl_rsrv_done_ff (
        .din(1'b1) ,
        .q(spu_mactl_rsrv_done_set),
        .en(spu_mactl_rsrv_done_wen),
        .rst(spu_mactl_rsrv_done_rst), .clk (rclk), .se(se), .si(), .so());
 
wire spu_mactl_rsrv_wrdetect_m2;
 
dff_s #(1) spu_mactl_rsrv_wrdetect_m_ff (
        .din(spu_mactl_rsrv_wrdetect_m) ,
        .q(spu_mactl_rsrv_wrdetect_m2),
        .clk (rclk), .se(se), .si(), .so());
 
 
assign spu_tlu_rsrv_illgl_m = spu_mactl_rsrv_wrdetect_m ;
 
// ----------------------------------------------
 
wire spu_mactl_rsrv_wrdetect_m3;
dff_s #(1) spu_mactl_rsrv_wrdetect_m2_ff (
        .din(spu_mactl_rsrv_wrdetect_m2) ,
        .q(spu_mactl_rsrv_wrdetect_m3),
        .clk (rclk), .se(se), .si(), .so());
 
wire ifu_spu_inst_vld_w2;
dff_s #(1) ifu_spu_inst_vld_w_dff (
        .din(ifu_spu_inst_vld_w) ,
        .q(ifu_spu_inst_vld_w2),
        .clk (rclk), .se(se), .si(), .so());
 
assign spu_mactl_rsrv_done_wen = ~spu_mactl_flush_g2 & ifu_spu_inst_vld_w2 & spu_mactl_rsrv_wrdetect_m3;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// ^^^^^^^^^^^^^^ ISSUE VALID SIGNAL ^^^^^^^^^^^^^^
// -------------------------------------------------------------------------
wire maop_vld_set;
 
wire maop_vld_rst = spu_mactl_ctl_rst_local | spu_mactl_iss_pulse_dly;
 
wire maop_vld_wen = spu_mactl_mactl_wen & ~spu_mactl_rsrv_wrdetect_m3;
 
assign spu_mactl_iss_pulse_pre = maop_vld_wen;
 
dffre_s  #(1) maop_vld_ff (
        .din(1'b1) ,
        .q(maop_vld_set),
        .en(maop_vld_wen),
        .rst(maop_vld_rst), .clk (rclk), .se(se), .si(), .so());
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
wire maop_vld_set_q;
 
dff_s  #(1) iss_pulse_ff (
        .din(maop_vld_set) ,
        .q(maop_vld_set_q),
        .clk (rclk), .se(se), .si(), .so());
 
 
assign spu_mactl_iss_pulse = ~maop_vld_set_q & maop_vld_set;
 
dff_s  #(1) iss_pulse_dly_ff (
        .din(spu_mactl_iss_pulse) ,
        .q(spu_mactl_iss_pulse_dly),
        .clk (rclk), .se(se), .si(), .so());
 
// -------------------------------------------------------------------------
// ^^^^^^^^^^^^^^^ OPCODE DECODE ^^^^^^^^^^^^^^^^
// -------------------------------------------------------------------------
// OPCODE decode.
wire [2:0] spu_madp_mactl_op;
 
assign spu_madp_mactl_op = spu_mactl_mactl_reg[8:6];
 
wire spu_mactl_ldop_pre = ~(|spu_madp_mactl_op[2:0]) ;
 
wire spu_mactl_stop_pre = ~spu_madp_mactl_op[2] & ~spu_madp_mactl_op[1] & 
				spu_madp_mactl_op[0];
 
wire spu_mactl_mulop_pre = ~spu_madp_mactl_op[2] & spu_madp_mactl_op[1] & 
				~spu_madp_mactl_op[0];
 
wire spu_mactl_redop_pre = ~spu_madp_mactl_op[2] & spu_madp_mactl_op[1] & 
				spu_madp_mactl_op[0] ;
 
wire spu_mactl_expop_pre = spu_madp_mactl_op[2] & ~spu_madp_mactl_op[1] & 
				~spu_madp_mactl_op[0];
 
dff_s #(1) ldop_ff (
        .din(spu_mactl_ldop_pre) ,
        .q(spu_mactl_ldop),
        .clk (rclk), .se(se), .si(), .so());
 
dff_s #(1) stop_ff (
        .din(spu_mactl_stop_pre) ,
        .q(spu_mactl_stop),
        .clk (rclk), .se(se), .si(), .so());
 
dff_s #(1) mulop_ff (
        .din(spu_mactl_mulop_pre) ,
        .q(spu_mactl_mulop),
        .clk (rclk), .se(se), .si(), .so());
 
dff_s #(1) redop_ff (
        .din(spu_mactl_redop_pre) ,
        .q(spu_mactl_redop),
        .clk (rclk), .se(se), .si(), .so());
 
dff_s #(1) expop_ff (
        .din(spu_mactl_expop_pre) ,
        .q(spu_mactl_expop),
        .clk (rclk), .se(se), .si(), .so());
 
 
// -------------------------------------------------------------------------
 
assign spu_mactl_mpa_sel = spu_mactl_ldop | spu_mactl_stop;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// ^^^^^^^^^^^^^^^ MEM WR/D ENABLE ^^^^^^^^^^^^^^^
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// the follwoing are for MAMEM(load) write and mux selection
/*******************************
 
MPA[3] MAADDR[0] | 
------------------------------
  0      0 	 | 128b	| eve+odd | mxsel[0]
  0      1 	 | 64b	| odd	  | mxsel[1]
  1      0 	 | 64b	| eve	  | mxsel[1]
  1      1 	 | 64b	| odd	  | mxsel[0]
 
********************************/
 
wire spu_mactl_memwen = spu_mamul_memwen | spu_maaeqb_memwen | spu_mald_memwen | spu_mared_memwen;
wire spu_mactl_memren = spu_mamul_memren | spu_maaeqb_memren |spu_mared_memren | spu_mast_memren |
				spu_maexp_memren;
 
assign spu_mactl_memeve_wen = ~spu_maaddr_maaddr_0 & spu_mactl_memwen;
assign spu_mactl_memodd_wen = (spu_maaddr_maaddr_0 & spu_mactl_memwen) | 
			(spu_mald_memwen & ~spu_maaddr_maaddr_0 & ~spu_maaddr_mpa_3 &
				spu_maaddr_nooddwr_on_leneq1);
 
wire mem_swap = (~spu_maaddr_mpa_3 & spu_maaddr_maaddr_0) |
	   	  (spu_maaddr_mpa_3 & ~spu_maaddr_maaddr_0);
 
wire [2:0] spu_mactl_memmxsel;
assign spu_mactl_memmxsel[2] = ~spu_mactl_ldop_pre; // its a mulop
assign spu_mactl_memmxsel[1] = spu_mactl_ldop_pre & mem_swap ;
assign spu_mactl_memmxsel[0] = spu_mactl_ldop_pre & ~mem_swap;
 
assign spu_mactl_memmxsel_l[2:0] = ~spu_mactl_memmxsel[2:0];
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
assign spu_mactl_mamem_ren = spu_mactl_memren;
assign spu_mactl_mamem_wen = spu_mactl_memwen;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// ^^^^^^^^^^^^^^ FLOP ENABLE FOR MA MUL/RED OPERATIONS ^^^^^^^^^^
// -------------------------------------------------------------------------
 
assign spu_mactl_madp_parflop_wen = spu_mared_not_idle | spu_mamul_oprnd2_bypass;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// ^^^^^^^^^^^^ PERR ^^^^^^^^^^^^^^
// -------------------------------------------------------------------------
 
wire spu_mactl_mamem_ren_dly1,spu_mactl_mamem_ren_dly2;
dff_s    #(2) dly_ren_ff (
        .din({spu_mactl_mamem_ren,spu_mactl_mamem_ren_dly1}) ,
        .q({spu_mactl_mamem_ren_dly1,spu_mactl_mamem_ren_dly2}),
        .clk (rclk), .se(se), .si(), .so());
 
 
wire spu_mactl_perr_wen = spu_madp_perr & spu_mactl_mamem_ren_dly2;
 
dffre_s  #(1) perr_ff (
        .din(1'b1) ,
        .q(spu_mactl_perr_set_int),
        .en(spu_mactl_perr_wen),
        //.rst(spu_mactl_ctl_rst_local | spu_mactl_iss_pulse_dly), .clk (rclk), .se(se), .si(), .so());
        .rst(spu_mactl_ctl_rst_local | spu_mactl_perr_rst), .clk (rclk), .se(se), .si(), .so());
 
assign spu_mactl_perr_set = spu_mactl_perr_set_int;
 
wire spu_mactl_perr_kill_op;
dff_s  #(1) perr_dly_ff (
        .din(spu_mactl_perr_wen) ,
        .q(spu_mactl_perr_kill_op),
        .clk (rclk), .se(se), .si(), .so());
 
 
 
assign spu_mactl_ma_kill_op = spu_mactl_perr_kill_op;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
// force perr during ma_ldop for testing only.
/*
wire [3:0] dumy_cntr_add,dumy_cntr_q;
 
wire dummy_count_eq = (dumy_cntr_q[3:0] == 4'b1001);
assign dumy_cntr_add[3:0] = dumy_cntr_q[3:0] + 4'b0001;
 
dffre_s  #(4) dumy_cntr_ff (
        .din(dumy_cntr_add[3:0]) ,
        .q(dumy_cntr_q[3:0]),
        .en(spu_mactl_ldop & lsu_spu_ldst_ack),
        .rst(spu_mactl_ctl_rst_local | (dummy_count_eq&lsu_spu_ldst_ack)  | spu_mactl_iss_pulse), .clk (rclk), .se(se), .si(), .so());
 
*/
 
//assign spu_mactl_force_perr = spu_mactl_mactl_reg[13] | (dummy_count_eq & spu_mactl_ldop);
assign spu_mactl_force_perr = spu_mactl_mactl_reg[13] ;
 
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
 
wire ldxa_tid_decode0 = ~spu_mactl_ldxa_tid_w[1] & ~spu_mactl_ldxa_tid_w[0];
wire ldxa_tid_decode1 = ~spu_mactl_ldxa_tid_w[1] & spu_mactl_ldxa_tid_w[0];
wire ldxa_tid_decode2 = spu_mactl_ldxa_tid_w[1] & ~spu_mactl_ldxa_tid_w[0];
wire ldxa_tid_decode3 = spu_mactl_ldxa_tid_w[1] & spu_mactl_ldxa_tid_w[0];
 
/*
dff_s  #(4) ifu_spu_nceen_ff (
        .din(ifu_spu_nceen[3:0]) ,
        .q(ifu_spu_nceen_q[3:0]),
        .clk (rclk), .se(se), .si(), .so()); 
*/
 
wire spu_mactl_nceen_w = 
                                (ifu_spu_nceen[0] & ldxa_tid_decode0) |
                                (ifu_spu_nceen[1] & ldxa_tid_decode1) |
                                (ifu_spu_nceen[2] & ldxa_tid_decode2) |
                                (ifu_spu_nceen[3] & ldxa_tid_decode3) ;
 
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
 
 
wire spu_ifu_corr_err_w =  spu_wen_ma_cor_err; // this is a pulse. 
 
dff_s  #(1) spu_ifu_corr_err_w2_ff (
        .din(spu_ifu_corr_err_w) ,
        .q(spu_ifu_corr_err_w2),
        .clk (rclk), .se(se), .si(), .so());
 
// ------------------------------------------------
 
 
wire spu_ifu_unc_err_w =  (spu_mactl_ttype_vld_dly | spu_mactl_ldxa_data_vld_qual_w) & 
						spu_wen_ma_unc_err;
 
assign spu_mactl_uncerr_rst = spu_ifu_unc_err_w;
// ------------------------------------------------
 
wire spu_lsu_unc_error_w = spu_mactl_ldxa_data_vld_qual_w &  spu_mactl_nceen_w & ~spu_mactl_int_set &
				(spu_mactl_perr_set_int | spu_wen_ma_unc_err) ;
 
// ------------------------------------------------
 
wire spu_ifu_mamem_err_w = (spu_mactl_ttype_vld_dly | spu_mactl_ldxa_data_vld_qual_w) & 
						spu_mactl_perr_set_int;
 
assign spu_mactl_perr_rst = spu_ifu_mamem_err_w;
// ------------------------------------------------
 
wire spu_ifu_int_set = spu_mactl_int_set;
 
 
dff_s  #(1) spu_ifu_int_w2_ff (
        .din(spu_ifu_int_set ) ,
        .q(spu_ifu_int_w2),
        .clk (rclk), .se(se), .si(), .so());
 
// ------------------------------------------------
 
wire spu_ifu_mamem_unc_w = spu_ifu_unc_err_w | spu_ifu_mamem_err_w;
 
 
dff_s  #(1) spu_ifu_mamem_unc_ff (
        .din(spu_ifu_mamem_unc_w ) ,
        .q(spu_ifu_mamem_unc_w2),
        .clk (rclk), .se(se), .si(), .so());
 
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.