⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem.v

📁 日立SH-2 CPU核的VERLOG源码
💻 V
📖 第 1 页 / 共 2 页
字号:
        else
            STATE <= NEXT_STATE;
    end

    // make IF_KEEP
    always @(ADR or IF_WIDTH) begin
        IF_KEEP <= (~ADR[1]) & (~ADR[0]) & IF_WIDTH;
    end

    // make IF_FORCE
    always @(IF_JP or IF_AD) begin
      //IF_FORCE <= IF_JP | ((~IF_AD[1]) & (~IF_AD[0]));
        IF_FORCE <= IF_JP | (~IF_AD[1]);
    end

    // make NEXT_STATE : state machine combinational circuit
    always @(STATE or IF_ISSUE or MA_ISSUE or IF_FORCE or IF_KEEP or ACK) begin
        case (STATE)
            `S_IDLE: // S0 idle
                     if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
                else NEXT_STATE <= `S_MAEX_IFPD;
            `S_IFEX: // S1 external fetch
                     if (ACK == 1'b0) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b000) NEXT_STATE <= `S_IDLE;
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b001) NEXT_STATE <= `S_IDLE_IFKP;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1000) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1010) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1001) NEXT_STATE <= `S_IFIN;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1011) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b010) NEXT_STATE <= `S_MAEX;
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b011) NEXT_STATE <= `S_MAEX_IFKP;
                else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b110) NEXT_STATE <= `S_MAEX_IFPD;
                else NEXT_STATE <= `S_MAEX_IFIN;
            `S_MAEX: // S2 external data access
                     if (ACK == 1'b0) NEXT_STATE <= `S_MAEX;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
                else NEXT_STATE <= `S_MAEX_IFPD;
            `S_MAEX_IFPD: // S3 external data access, pending fetch
                     if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFPD;
                else NEXT_STATE <= `S_IFEX;
            `S_IDLE_IFKP: // S4 idle, keeping lower un-decodeed instruction
                     if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b101) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b100) NEXT_STATE <= `S_IFIN;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX_IFKP;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b111) NEXT_STATE <= `S_MAEX_IFPD;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b110) NEXT_STATE <= `S_MAEX_IFIN;
                else NEXT_STATE <= `S_IDLE_IFKP;
            `S_IFIN: // S5 internal fetch from just keeping one
                     if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
                else NEXT_STATE <= `S_MAEX_IFPD;
            `S_MAEX_IFKP: // S6 extenal data access, keeping lower un- decoded instruction
                     if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFKP;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b101) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b100) NEXT_STATE <= `S_IFIN;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX_IFKP;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b111) NEXT_STATE <= `S_MAEX_IFPD;
                else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b110) NEXT_STATE <= `S_MAEX_IFIN;
                else NEXT_STATE <= `S_IDLE_IFKP;
            `S_MAEX_IFIN: // S7 external data access and do internal fetch from just keeping
                     if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFIN;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
                else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
                else NEXT_STATE <= `S_MAEX_IFPD;
            
            default: NEXT_STATE <= `S_IDLE;
        endcase
    end            

//-------------------------------
// ADR : external addresss output
//-------------------------------
    // selector
    always @(NEXT_STATE or MA_AD or IF_AD) begin
        if (NEXT_STATE[1] == 1'b1) //memory access
            ADR_PREV <= MA_AD;
        else                       // instruction fetch
            ADR_PREV <= IF_AD;
    end
    // output
    always @(posedge CLK) begin
        if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
            ADR <= ADR_PREV;
        end
    end

//-------------------------------------
// ACCESS_SZ : current data access size
//-------------------------------------
    always @(posedge CLK) begin
        if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
            ACCESS_SZ <= MA_SZ; // have meaning only when data access
        end
    end

//----------------------------
// DATO : external data output
//----------------------------
    // prepare
    always @(MA_SZ or MA_DW) begin
        case (MA_SZ)
            2'b00: begin // byte
                       DATO_PREV[31:24] <= MA_DW[7:0];
                       DATO_PREV[23:16] <= MA_DW[7:0];
                       DATO_PREV[15: 8] <= MA_DW[7:0];
                       DATO_PREV[ 7: 0] <= MA_DW[7:0];
                   end
            2'b01: begin // word
                       DATO_PREV[31:24] <= MA_DW[15:8];
                       DATO_PREV[23:16] <= MA_DW[ 7:0];
                       DATO_PREV[15: 8] <= MA_DW[15:8];
                       DATO_PREV[ 7: 0] <= MA_DW[ 7:0];
                   end
            2'b10: begin // long
                       DATO_PREV[31:24] <= MA_DW[31:24];
                       DATO_PREV[23:16] <= MA_DW[23:16];
                       DATO_PREV[15: 8] <= MA_DW[15: 8];
                       DATO_PREV[ 7: 0] <= MA_DW[ 7: 0];
                   end
            default: // 2'b11 don't care
                   begin
                       DATO_PREV[31:24] <= MA_DW[31:24]; // Thorn Aitch 2003/12/10
                       DATO_PREV[23:16] <= MA_DW[23:16]; // Thorn Aitch 2003/12/10
                       DATO_PREV[15: 8] <= MA_DW[15: 8]; // Thorn Aitch 2003/12/10
                       DATO_PREV[ 7: 0] <= MA_DW[15: 8]; // Thorn Aitch 2003/12/10
                   end
        endcase
    end

    // output
    always @(posedge CLK) begin
        if ((NXTBUS == 1'b1) && (MEMEND == 1'b1) && (MA_WR == 1'b1))
            DATO <= DATO_PREV;
    end

//----------------------------
// IF_DR : fetched instruction
//----------------------------
    // capture DATI    
    always @(posedge CLK) begin
        if ((MEMEND == 1'b1) & ((STATE == `S_IFEX) | ((STATE[2] == 1'b1) && (STATE[0] == 1'b1))))
        begin
            IF_STATE   <= STATE;
            IF_ADR1    <= ADR[1];
            IF_IF_BUF  <= IF_BUF;
            IF_DR_PREV <= DATI;
        end
    end
    // output to IF_DR
    always @(IF_STATE or IF_ADR1 or IF_DR_PREV or IF_IF_BUF) begin
        if (IF_STATE == `S_IFEX)
            begin
                // IF from 0,4,8,C
                if (IF_ADR1 == 1'b0)
                    begin
                        IF_DR <= IF_DR_PREV[31:16];
                    end
                // IF from 2,6,A,E
                else
                    IF_DR <= IF_DR_PREV[15:0];
            end
        else
        // IF from IF_BUF
            //if ((IF_STATE[2] == 1'b1) && (IF_STATE[0] == 1'b1)) // `S_IFIN or `S_MAEX_IFIN
            //    IF_DR <= IF_IF_BUF;	    // Thorn Aitch 2003/12/10
            //else 					    // Thorn Aitch 2003/12/10
            //    IF_DR <= 32'hxxxxxxxx;    // Thorn Aitch 2003/12/10
		  IF_DR <= IF_IF_BUF;		    // Thorn Aitch 2003/12/10
    end
    // output
    //always @(posedge CLK) begin
    //   if ((MEMEND == 1'b1) & ((STATE == `S_IFEX) | ((STATE[2] == 1'b1) && (STATE[0] == 1'b1))))
    //    begin
    //        IF_DR <= IF_DR_PREV;
    //    end
    //end

//---------------------------------------------------------------
// IF_BUF : buffer to keep the lower 16bit of previous long fetch
//---------------------------------------------------------------
    always @(posedge CLK) begin
        if (MEMEND == 1'b1) begin
            if (STATE == `S_IFEX)
                // IF from long space external
                if ((IF_WIDTH == 1'b1) && (ADR[1] == 1'b0))
                    IF_BUF <= DATI[15:0];
        end
    end

//------------------
// MA_DR : read data
//------------------
    // capture DATI
    always @(posedge CLK) begin
        if (ACK == 1'b1) begin // it must be captured by ACK (not MEMEND)
            if ((STATE[1] == 1'b1) && (WE == 1'b0)) begin
                MA_ACCESS_SZ <= ACCESS_SZ;
                MA_ADR <= ADR[1:0];
                MA_DR_PREV <= DATI;
            end
        end
    end
   // output to MA_DR with Sign Extended
    always @(MA_ACCESS_SZ or MA_DR_PREV or MA_ADR) begin
        case (MA_ACCESS_SZ)
            2'b00: begin //byte
                       if ({MA_ADR[1], MA_ADR[0]} == 2'b00)
                           begin
                               for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[31];
                               MA_DR[7:0] <= MA_DR_PREV[31:24];
                           end
                       else if ({MA_ADR[1], MA_ADR[0]} == 2'b01)
                           begin
                               for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[23];
                               MA_DR[7:0] <= MA_DR_PREV[23:16];
                           end
                       else if ({MA_ADR[1], MA_ADR[0]} == 2'b10)
                           begin
                               for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[15];
                               MA_DR[7:0] <= MA_DR_PREV[15:8];
                           end
                       else if ({MA_ADR[1], MA_ADR[0]} == 2'b11)
                           begin
                               for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[7];
                               MA_DR[7:0] <= MA_DR_PREV[7:0];
                           end
                   end
            2'b01: begin //word
                       if (MA_ADR[1] == 1'b0)
                           begin
                               for (i = 16 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[31];
                               MA_DR[15:0] <= MA_DR_PREV[31:16];
                           end
                       else
                           begin
                               for (i = 16 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[15];
                               MA_DR[15:0] <= MA_DR_PREV[15:0];
                           end
                   end
            2'b10: begin //long
                       MA_DR[31:0] <= MA_DR_PREV[31:0];
                   end
            default : begin
                          //MA_DR[31:0] <= 32'hxxxxxxxx;    // Thorn Aitch 2003/12/10 
					 MA_DR[31:0] <= MA_DR_PREV[31:0];  // Thorn Aitch 2003/12/10
                      end
        endcase
    end
    // output
    //always @(posedge CLK) begin
    //    if (ACK == 1'b1) begin // it must be captured by ACK (not MEMEND)
    //        if ((STATE[1] == 1'b1) && (WE == 1'b0)) begin
    //            MA_DR <= MA_DR_PREV;
    //        end
    //    end
    //end

//------------------------------------------
// IF_BUS : fetch access done to extenal bus
//------------------------------------------
    always @(posedge CLK) begin
        if (MEMEND == 1'b1) begin
            if (NEXT_STATE == `S_IFEX)
                IF_BUS <= 1'b1;
           else
                IF_BUS <= 1'b0;
        end
    end

//----------------------------------------------
// IF_STALL : fetch and memory access contention
//----------------------------------------------
    always @(NEXT_STATE) begin
        if (NEXT_STATE == `S_MAEX_IFPD)
            IF_STALL <= 1'b1;
        else
            IF_STALL <= 1'b0;
    end

//-------------------------
// WE : WISHBONE write/read
//-------------------------
    // WE
    always @(posedge CLK) begin
        if (MEMEND == 1'b1) begin
            if (((NEXT_STATE[1] == 1'b1) && (MA_WR == 1'b0)) || (NEXT_STATE == `S_IFEX))
                WE <= 1'b0; // read
            else
                WE <= 1'b1; // write
        end
    end

//--------------------------
// STB : WISHBONE bus strobe
//--------------------------
    always @(posedge CLK) begin
        if (MEMEND == 1'b1) begin
            STB <= NXTBUS;
        end
    end

//------------------------------------
// CYC :WOSHBONE show cycle to be kept
//------------------------------------
    //     req     STB CYC
    //     ---------------
    //     RD,CYC  off off
    //     nop     on  on
    //     WR      off on
    //     nop     on  on
    //             off off  
    // prepare
    always @(NXTBUS or NEXT_KEEP_CYC) begin
        if ((NXTBUS == 1'b1) || (NEXT_KEEP_CYC == 1'b1))
            CYC_PREV <= 1'b1;
        else 
            CYC_PREV <= 1'b0;
    end
    // remember for next cyc
    always @(posedge CLK) begin
        if (MEMEND == 1'b1) begin
            NEXT_KEEP_CYC <= KEEP_CYC;
        end
    end
    // output
    always @(posedge CLK) begin
        if (MEMEND == 1'b1) begin
            CYC <= CYC_PREV;
        end
    end

//----------------------------------------
// SEL : WISHBONE show valid data position
//----------------------------------------
    // prepare
    always @(NEXT_STATE or MA_SZ or MA_AD or IF_AD) begin
      //if ((NEXT_STATE == `S_IFEX) && (IF_AD[1:0] == 2'b00))
        if ((NEXT_STATE == `S_IFEX) && (IF_AD[1] == 1'b0))
            SEL_PREV <= 4'b1111;
      //else if ((NEXT_STATE == `S_IFEX) && (IF_AD[1:0] == 2'b10))
        else if ((NEXT_STATE == `S_IFEX) && (IF_AD[1] == 1'b1))
            SEL_PREV <= 4'b0011;
        else 
            if (NEXT_STATE[1] == 1'b1)
                begin
                    if (MA_SZ == 2'b10)
                        SEL_PREV <= 4'b1111;
                    else if ((MA_SZ == 2'b01) && (MA_AD[1] == 1'b0))
                        SEL_PREV <= 4'b1100;
                    else if ((MA_SZ == 2'b01) && (MA_AD[1] == 1'b1))
                        SEL_PREV <= 4'b0011;
                    else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b00))
                        SEL_PREV <= 4'b1000;
                    else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b01))
                        SEL_PREV <= 4'b0100;
                    else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b10))
                        SEL_PREV <= 4'b0010;
                    else //if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b11))
                        SEL_PREV <= 4'b0001;
                end
            else SEL_PREV <= 4'b0000;
    end
    // output
    always @(posedge CLK) begin
        if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
            SEL <= SEL_PREV;
        end
    end

//======================================================
  endmodule
//======================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -