/*
 * File:        pippo_pipectrl.v
 * Project:     pippo
 * Designer:    kiss@pwrsemi
 * Mainteiner:  kiss@pwrsemi
 * Checker:
 * Assigner:    
 * Description:
 *      Á÷Ë®Ïß¿ØÖÆÐÅºÅ£¬Ö÷Òª²úÉú
 *          pc_freeze£º¶³½áPC¼Ä´æÆ÷£¬±£´æµ±Ç°Öµ
 *          if_freeze£º±íÊ¾IF¶ÎÎÞ·¨½ÓÊÜÐÂ²Ù×÷
 *          id_freeze£º±íÊ¾ID¶ÎÎÞ·¨½ÓÊÜÐÂ²Ù×÷
 *          ex_freeze£º±íÊ¾EXE¶ÎÎÞ·¨½ÓÊÜÐÂ²Ù×÷
 *          wb_freeze£º¶³½áÐ´»Ø²Ù×÷£¬ÓÉÓÚÄ¿Ç°µÄÈý¼¶Á÷Ë®Éè¼Æ£¬wb_freezeµÈÍ¬ÓÚex_freeze
 *      ÒÔ¿ØÖÆÁ÷Ë®Ïß¼Ä´æÆ÷£¨Ö÷ÒªÊÇxx_ciaºÍxx_instµÈ£©ÐÐÎª¡£
 * Specification
    1. ¶³½áÁ÷Ë®Ïß
        ÔÚÁ÷Ë®ÏßÓöµ½ÒÔÏÂÇéÐÎ£¬±ØÐë¶ÔÁ÷Ë®ÏßÊ©¼Ó¿ØÖÆÒÔ±£Ö¤Ö¸ÁîÁ÷Ë³ÐòÖ´ÐÐ²¢Íê³É¡£
        £¨1£©	Ä³Ð©Ö¸ÁîÀàÐÍÐèÒªÔö¼ÓÁ÷Ë®¼¶£¬Èç·Ã´æÖ¸ÁîÐèÔö¼ÓMAÁ÷Ë®¼¶
        £¨2£©	Ä³Á÷Ë®¶ÎÓÉÓÚ¸÷ÖÖÔ­ÒòÐèÒª¶à¸öÖÜÆÚÍê³ÉÊ±£¬Èç¸´ÔÓËãÊõÔËËãÖ¸Áî
        £¨3£©	Ö¸ÁîÖ´ÐÐÊ§°Ü£¬Èç·Ã´æÖ¸ÁîÒý·¢µÄÖÐ¶Ï£¬ÐèÒªÖÐÖ¹Ö¸ÁîµÄÍê³É
        £¨4£©   ÒÔÉÏ¶àÖÖÇé¿öÍ¬Ê±·¢Éú£¨·Ã´æÖ¸Áî·ÃÎÊ»º´æµ«miss£© 
        ¸÷Á÷Ë®½×¶ÎÒý·¢µÄstallÇëÇóÈçÏÂ£º
            IF¶Î£ºÈ¡»ØÖ¸ÁîµÄµÈ´ýÖÜÆÚ£¬ÓÐifÄ£¿éµÄif_stallÇëÇó
            ID¶Î£ºÎÞ£¨ÒëÂë¼ì²âµ½·ÖÖ§Ö¸Áî£¬ÓÐidÄ£¿éµÄbp_stallÇëÇó£©
            EX¶Î£º¶àÖÜÆÚÖ´ÐÐ²Ù×÷£¨·Ã´æºÍ¸´ÔÓËãÊõÔËËãÖ¸Áî£©£¬ÓÐlsu_stallºÍmulticycle_stallÇëÇó
        ÔÚ×ÛºÏÆÀ¹ÀÁ÷Ë®Ïß×´Ì¬ºÍstallÇëÇóÖ®ºó£¬²úÉúfreezeÐÅºÅ¿ØÖÆÁ÷Ë®ÏßÍÆ½ø£­Õý³£Á÷¶¯£¬²åÈëBubble£¨NOP»òKCS£©µÈ
        ¸÷Á÷Ë®¶Î¶³½á£¨freeze£©¹æÔò£ºµ±ÏÖ½×¶Î²úÉústallÇëÇó£¬Ç°Ò»¼¶Á÷Ë®±ØÐë¶³½á£¬ÒÔ±ÜÃâoverlapping
            µ±µÚÒ»¼¶Á÷Ë®(IF)³öÏÖstallÇëÇóÊ±£¬IF¶Î¶³½á
                [Í¬Ò»ÖÜÆÚÄÚIF miss I$£¬·Ã´æÖ¸Áîhit D$µÄÇé¿ö]
        ¶³½áÐÅºÅÓ¦ÓÃ¹æÔòÈçÏÂ£ºÃ¿Ò»¼¶µÄÁ÷Ë®¼Ä´æÆ÷Î¬»¤ÊÜÇ°ºóÁ½¼¶Á÷Ë®ÏßµÄfreezeÐÅºÅ¿ØÖÆ¡£
            µ±Ç°¶Ë¶³½áºó¶ËÕý³£Ê±£¬²åÈëNOP£»
            µ±Ç°¶Ë¶³½áºó¶Ë¶³½áÊ±£¬±£³Öµ±Ç°×´Ì¬£»
            µ±Ç°¶ËÕý³£ºó¶ËÕý³£Ê±£¬Õý³£ÍÆ½ø
            Ç°¶ËÕý³£ºó¶Ë¶³½áµÄÇé¿ö²»·ûºÏfreezeÐÅºÅ²úÉú¹æÔò
    2. Ë¢ÐÂÁ÷Ë®Ïß
        ³ýÊÜfreezeÐÅºÅ¿ØÖÆÍâ£¬Á÷Ë®ÏßÔÚÏÂÃæÇé¿öÏÂÐèÒªË¢ÐÂÁ÷Ë®Ïß£­ÅÅ¿ÕÏÖÓÐÖ¸Áî£¬ÖØÐÂÈ¡Ö¸
        £¨1£©ÖÐ¶Ï´¦ÀíÄ£¿é²úÉúµÄflush_exceptÒÔË¢ÐÂÁ÷Ë®Ïß
        £¨2£©·ÖÖ§´¦ÀíÄ£¿éÓÉÓÚ·ÖÖ§Ô¤²â´íÎó²úÉúµÄflush_branchÒÔË¢ÐÂÁ÷Ë®Ïß
    3. PCÎ¬»¤ºÍ¸üÐÂ
        PCÎ¬»¤ºÍ¸üÐÂÓÐÁ½ÖÖÇé¿öÐèÒª·Ö¿ª´¦Àí
        £¨1£©Á÷Ë®Ïß¶³½áÊ±£¬±£³ÖÏÖÓÐÈ¡Ö¸µØÖ·PC£¬´ý¶³½á½â³ýºó¼ÌÐøÈ¡Ö¸
        £¨2£©Á÷Ë®ÏßË¢ÐÂÊ±£¬ÐèÒª·ÅÆúÏÖÓÐPC£¬´ýË¢ÐÂÍê³Éºó·Ö±ðÊ¹ÓÃnpc_xxxÖØÐÂÈ¡Ö¸
        pc_freezeÔÚ´ÓÓÐÐ§×´Ì¬»Ö¸´Ê±£¬
 * List2do: 
 *      [TBV] timing relationship between flushpipe and freeze.
 *
 */

// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "def_pippo.v"

module pippo_pipectrl(

	flush_except, flush_branch, flushpipe, 

	if_stall, lsu_stall, multicycle_cnt, asyn_stall, 

	pc_freeze, if_freeze, id_freeze, ex_freeze, wb_freeze
);

//
// I/O
//

// stall request from pipeline stages
input				if_stall;                       
input				lsu_stall;      
input               asyn_stall;
input   [1:0]	    multicycle_cnt; 

// freeze command to pipeline stages
output				pc_freeze;
output				if_freeze;
output				id_freeze;
output				ex_freeze;
output				wb_freeze;

// flush control
input				flush_except;
input               flush_branch;
output              flushpipe; 

//
// Internal wires and regs
//
wire			multicycle_stall;

//
// flush pipelining 
//  at the last cycle of flushpipe assertion, new fetch address will send to pc register
//  1. when flush is raised by except processing, assert for two cycles.
//  2. when flush is raised by branch processing, assert for one cycle.
//
assign flushpipe = flush_except | flush_branch; 

//
// PC freeze signal
//
// pc_freeze is just for dis-asserting fetch request
assign pc_freeze = flushpipe;

//
// Pipeline freeze generation:
//

assign multicycle_stall = |multicycle_cnt;

// notes for asyn_stall: see except module
assign if_freeze = if_stall | id_freeze;
assign id_freeze = ex_freeze;
assign ex_freeze = wb_freeze | asyn_stall; 
assign wb_freeze = lsu_stall | multicycle_stall;

/*
Implementation: Memory access instructions with update, under 3r1w rf design

a. Load with update instructions
    pipectrl.v
        ×¢Òâ£ºmulticycle_stallÌõ¼þÒ²Ðë±ä»¯£¬µ±wb_twiceÓÐÐ§Ê±£¬ÏÂÒ»ÌõÖ¸ÁîÒýÆðmulticycle_stall²»ÄÜÖÃÆð
    rf.v
      we & (~wb_freeze | wb_at_fze)  //write enable logic  
    wb_twice come from rfwbop, and more to do:
        1. logic for write address and source
        2. write order of EA and loaded data?
        3. wb_atfzeÓÐÐ§Ê±¼äÖ»ÄÜÒ»ÅÄ    
b. Store with update instructions
    ×¢ÒâÐèÒªÍ¬²½storeµÄÍê³ÉºÍupdate£¨Ð´EA»ØRA£©µÄÍê³É

Logic.a: ¿ÉÒÔÐ´»ØÊ±£¬¶³½áwb£¬Ð´»ØÒ»´Î£¬ÔÙ½â¶³Íê³ÉµÚ¶þ´ÎÐ´»Ø£»
  pipectrl.v
    //wb_atfze means: wb_freeze is asserted by wb_twice only, at this case, write-back can go.
    assign wb_freeze_a = lsu_stall | multicycle_stall;
    assign wb_freeze = wb_freeze_a | wb_atfze;

    always @(posedge clk or posedge rst) begin
    	if (rst)
    		wb_atfze <= #1 1'b0;
    	else if(wb_freeze_a)         
    		wb_atfze <= #1 rfwb_uops[0] & rfwb_uops[1];
        else
            wb_atfze <= #1 1'b0;
    end

  reg_gprs.v
    assign rf_we = (~flushpipe) & ((wea & ~wb_freeze) |(wea & wb_atfze) | (web & ~wb_freeze)) ;
    assign rf_addrw = wea & (!web | wb_atfze) ? addrwa : web ? addrwb : 5'd0;
    assign rf_dataw = wea & (!web | wb_atfze) ? datawa : web ? datawb : 32'd0;
  
  operandmux.v/wbmux.v
    Èç¹ûÊ¹ÓÃ×ª·¢Âß¼­£¬ÔòwraºÍwrbµÄ×ª·¢ÐèÒªÔö¼ÓÓÐÐ§Âß¼­£»¼Æ»®ÊµÏÖÓÚwbmuxÄ£¿é
        (gpr_addr_rda == ex_gpr_addr_wra) && (ex_rfwb_uops[0] & !ex_rfwb_uops[1])
        (gpr_addr_rda == ex_gpr_addr_wrb) && (ex_rfwb_uops[1] & !wb_atfze)
  
Logic.b: ÏÈÐ´»ØÒ»´Î£¬ÔÙ¶³½áwb¶ÎÍê³ÉµÚ¶þ´ÎÐ´»Ø£»µ¼ÖÂÎÊÌâ£º
    1£¬ÏÂÒ»ÌõÖ¸ÁîÒÑ¾­½øÈëexe¶Î£¬Èç¹ûÊÇ¶àÖÜÆÚÖ¸ÁîÔò»áµ¼ÖÂwb_atfze±£³ÖÓÐÐ§
    2£¬ÐèÒª¼Ä´æaddr_wrºÍeaµÈ
assign wb_freeze_a = lsu_stall | multicycle_stall;
assign wb_freeze = wb_freeze_a | wb_atfze;

always @(posedge clk or posedge rst) begin
	if (rst)
		wb_atfze <= #1 1'b0;
	else if(!wb_freeze_a)         
		wb_atfze <= #1 rfwb_uops[0] & rfwb_uops[1];
end


*/

endmodule
