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

📄 risc16f84_clk2x.v

📁 VGA/LCD Corev2.0Specifications
💻 V
📖 第 1 页 / 共 3 页
字号:
      sleepflag_reg   <= 0;
      status_reg[4]   <= 1;     // /T0 = 1
      status_reg[3]   <= 1;     // /PD = 1
      stack_pnt_reg   <= 0;     // Reset stack pointer

      // go to Q2 state if reset signal is de-asserted
      if (~reset_i) state_reg <= Q2_PP;

    end  // End of QRESET_PP state


    // 2-3. Q2 cycle
    Q2_PP :
    begin
      ram_we_reg <= 0;  // Default to not writing (Can be overridden below)
      aux_we_reg <= 0;  // Default to not writing (Can be overridden below)
      
      // 2-3-1. Read data-RAM and substitute source values to alu-input regs
      if (exec_op_reg && ~intstart_reg && ~sleepflag_reg)  // Not stalled
      begin
        // 2-3-1-1. Set aluinp1 register (source #1)
        if (   inst_movf   || inst_swapf || inst_addwf || inst_subwf
            || inst_andwf  || inst_iorwf || inst_xorwf || inst_decf
            || inst_incf   || inst_rlf   || inst_rrf   || inst_bcf
            || inst_bsf    || inst_btfsc || inst_btfss || inst_decfsz
            || inst_incfsz || inst_comf)
            
            aluinp1_reg <= ram_i_node;       // RAM/Special registers
        else
        if (   inst_movlw || inst_addlw || inst_sublw || inst_andlw
            || inst_iorlw || inst_xorlw || inst_retlw)
            
            aluinp1_reg <= inst_reg[7:0];    // Immediate value ("k")
        else
        if (   inst_clrf  || inst_clrw) aluinp1_reg <= 0; // 0
        else aluinp1_reg <= w_reg;                        // W register
        
        // 2-3-1-2. Set aluinp2 register (source #2)
        c_in <= 0; // Default to no carry in.
        if      (inst_decf || inst_decfsz) aluinp2_reg <= -1; // for decr.
        else if (inst_incf || inst_incfsz) aluinp2_reg <=  1; // for incr.
                // -1 * W register (for subtract)
        else if (inst_sublw || inst_subwf) 
        begin
          aluinp2_reg <= ~w_reg + 1; 
          c_in <= 1;  // Set c_in for subtract operations (makes C come out).
        end
                // operation of BCF: AND with inverted mask ("1..101..1")
                // mask for BCF: value of only one position is 0
        else if (inst_bcf) aluinp2_reg <= ~mask_node; 
                // operation of BSF: OR with mask_node ("0..010..0")
                // operation of FSC and FSS: AND with mask_node, compare to 0
        else if (inst_btfsc || inst_btfss || inst_bsf)
                                      aluinp2_reg <= mask_node;
        else aluinp2_reg <= w_reg; // W register

        // 2-3-1-3. Set stack pointer register (pop stack)
        if (inst_ret || inst_retlw || inst_retfie)
             stack_pnt_reg   <= stack_pnt_reg - 1; // cycles 3,2,1,0,7,6...

        // 2-4-1-3. Set data-SRAM write enable (hazard-free)
        if (writeram_node && addr_sram)    ram_we_reg <= 1;
        if (writeram_node && addr_aux_dat) aux_we_reg <= 1;

      end  // End of "if not stalled"

      // 2-3-4. Goto next cycle
      if (reset_i) state_reg <= QRESET_PP;
      // if in sleep mode, wait until wake-up trigger comes
      else if (sleepflag_reg && ~intstart_reg)  // Sleeping, not stalled
      begin
        if (inte_sync_reg)
        begin
        // if rb0/inte interrupt comes, then resume execution
          sleepflag_reg <= 0;
          state_reg     <= Q2_PP;
        end
      end
      else state_reg <= Q4_PP;

    end   // End of Q2 state

    // 2-5. Q4 cycle
    Q4_PP :
    begin
      int_node <= 0;     // Default state is: no interrupt request
      
      if (exec_op_reg && ~intstart_reg)      // if NOT STALLED
      begin
        // 2-4-1-2. Set C flag and DC flag
        if (inst_addlw || inst_addwf || inst_sublw || inst_subwf)
        begin
          status_reg[1]   <= addlow_node[4];         // DC flag
          status_reg[0]   <= add_node[8];            // C flag
        end
        else if (inst_rlf) status_reg[0] <= aluinp1_reg[7];  // C flag
        else if (inst_rrf) status_reg[0] <= aluinp1_reg[0];  // C flag
      end

      // 2-4-2. Check external interrupt and set int. flag
      if (~intstart_reg && intcon_reg[7]) // GIE
      begin
        // PORT-B0 INT
        if (inte_sync_reg)
        begin
          intcon_reg[1] <= 1;     // set INTF
          intclr_reg    <= 1;     // clear external int-register
                                  // (intrise_reg and intdown_reg)
          int_node      <= 1;     // Flag ensures that PC is held, and that
                                  // GIE bit is set appropriately by logic
                                  // further "downstream" within this state.
        end
      end

      if (~exec_op_reg && ~intstart_reg)      // if STALLED (not interrupt) 
      begin
        pc_reg          <= inc_pc_node; // increment PC
        exec_op_reg     <= 1;           // end of stall
      end
      else  // if NOT stalled 
      begin
        // (note: if intstart_reg, only stack/pc-operations in this 
        //        else-clause will be performed)
        // 2-5-2. Store calculation result into destination, 
        // set PC and flags, and determine if execute next cycle.

        // 2-5-2-1. Set W register, if not in stall cycle 
        //          (~intstart_reg) and destination is W
        
        // writew_node == 0 if intstart_reg...
        if (writew_node) w_reg   <= aluout;    // write W reg

        // 2-5-2-2. Set data RAM/special registers,
        // if not in stall cycle (~intstart_reg)
        if (writeram_node)
        begin
          if (addr_stat)
          begin
            status_reg[7:5] <= aluout[7:5];      // write IRP,RP1,RP0
            // status(4),status(3)...unwritable, see below (/PD,/T0 part)
            status_reg[1:0] <= aluout[1:0];      // write DC,C
          end
          if (addr_fsr)         fsr_reg <= aluout;      // write FSR
          if (addr_pclath)   pclath_reg <= aluout[4:0]; // write PCLATH
          if (addr_intcon) intcon_reg[6:0] <= aluout[6:0]; 
                           // write INTCON (except GIE)
                           // intcon(7)...see below (GIE part)
          if (addr_option)   option_reg <= aluout;       // write OPTION
          if (addr_aux_adr_lo) aux_adr_lo_reg <= aluout; // write AUX low
          if (addr_aux_adr_hi) aux_adr_hi_reg <= aluout; // write AUX high
        end

        // 2-5-2-3. Set/clear Z flag, if not in stall cycle (~intstart_reg)
        if (~intstart_reg)
        begin
          if (addr_stat) status_reg[2] <= aluout[2]; // (dest. is Z flag)
          else if (   inst_addlw || inst_addwf || inst_andlw || inst_andwf
                   || inst_clrf  || inst_clrw  || inst_comf  || inst_decf
                   || inst_incf  || inst_movf  || inst_sublw || inst_subwf
                   || inst_xorlw || inst_xorwf || inst_iorlw || inst_iorwf )
                  status_reg[2] <= aluout_zero_node; // Z=1 if result == 0
        end

        // 2-5-2-4. Set PC and determine whether to execute next cycle or not
        // After interrupt-stall cycle ends, jump to interrupt vector
        if (intstart_reg) 
        begin
          pc_reg      <= 4;     // (interrupt vector)
          exec_op_reg <= 0;     // the next cycle is a stall cycle
        end
        else if (inst_ret || inst_retlw || inst_retfie) // "return" instr.
        begin
          pc_reg      <= stack_reg[stack_pnt_reg];
          exec_op_reg <= 0;              // the next cycle is stall cycle
        end
        else if (inst_goto || inst_call) // "goto/call" instructions
        begin
          // (see pp.18 of PIC16F84 data sheet)
          pc_reg      <= {pclath_reg[4:3],inst_reg[10:0]};
          exec_op_reg <= 0;
        end
        else if ( (   (inst_btfsc || inst_decfsz || inst_incfsz) 
                       && aluout_zero_node)
                   || (inst_btfss && ~aluout_zero_node)
                   ) // bit_test instrcutions
        begin
          pc_reg      <= inc_pc_node;
          exec_op_reg <= 0;
          // the next cycle is stall cycle, if test conditions are met.
        end
        else if (writeram_node && addr_pcl) // PCL is data-destination
        begin
          // (see pp.18 of PIC16F84 data sheet)
          pc_reg      <= pclath_reg[4:0] & aluout;
          exec_op_reg <= 0;
        end
        else
        begin
          // this check MUST be located AFTER the above if/else sentences
          // check if interrupt trigger comes
          if (~int_node) pc_reg <= inc_pc_node; 
          // if not, the next instr. fetch/exec. will be performed normally
          else pc_reg <= pc_reg; 
          // if so, value of PC must be held 
          //(will be pushed onto stack at the end of next instruction cycle)
          exec_op_reg <= 1;
        end

        // 2-5-2-5. Push current PC value into stack, if necessary
        if (inst_call || intstart_reg)
        // CALL instr. or End of interrupt-stall cycle
        begin
          stack_reg[stack_pnt_reg] <= pc_reg;  // write PC value
          stack_pnt_reg <= stack_pnt_reg + 1;  // increment stack pointer
        end

        // 2-5-2-6. Set GIE bit in intcon register (intcon_reg(7))
        if (~intstart_reg)
        begin
          if (int_node) // interrupt trigger comes
          begin
            intcon_reg[7] <= 0; // clear GIE
            intstart_reg  <= 1; // the next cycle is interrupt-stall cycle
          end
          else if (inst_retfie) // "return from interrupt" instruction
          begin
            intcon_reg[7] <= 1;
            intstart_reg  <= 0;
          end
          else if (writeram_node && addr_intcon) // destination is GIE
          begin
            intcon_reg[7] <= aluout[7];
            intstart_reg  <= 0;
          end
          else intstart_reg <= 0;
        end
        else intstart_reg <= 0;

        // 2-5-2-7. Enter sleep mode if needed. (No need to set /TO and /PD)
        if (~intstart_reg && inst_sleep) sleepflag_reg <= 1;

      end // (if not stalled)

      // 2-5-3. Clear data-SRAM write enable (hazard-free)
      ram_we_reg <= 0;
      aux_we_reg <= 0;

      // 2-5-1. Fetch next program-instruction
      inst_reg    <= prog_dat_i;

      // 2-5-6. Goto next cycle
      if (reset_i) state_reg   <= QRESET_PP;
      else state_reg   <= Q2_PP;
    end    // End of Q4 state

    // 2-6. Illegal states (NEVER REACHED in normal execution)
    default : state_reg   <= QRESET_PP;      // goto reset state
    endcase;
    
end  // End of global clock enable
end  // End of process


// Detect external interrupt requests
// INT0 I/F
always @(posedge int0_i or posedge intclr_reg)
begin
  if (intclr_reg) intrise_reg <= 0;
  else intrise_reg <= 1; // catch positive edge
end // process

always @(negedge int0_i or posedge intclr_reg)
begin
  if (intclr_reg) intdown_reg <= 0;
  else intdown_reg <= 1; // catch negative edge
end // process
assign rb0_int = option_reg[6]?intrise_reg:intdown_reg;

// Decode INT triggers 
// (do not AND with GIE(intcon_reg(7)), since these signals are 
//  also used for waking up from SLEEP)
assign inte  = intcon_reg[4] && rb0_int;                                       // G0IE and raw-trigger signal


// Circuit's output signals
assign prog_adr_o = pc_reg;        // program ROM address
assign ram_adr_o  = ram_adr_node;  // data RAM address
assign ram_dat_o  = aluout;        // data RAM write data
assign ram_we_o   = ram_we_reg;    // data RAM write enable

assign aux_adr_o  = {aux_adr_hi_reg,aux_adr_lo_reg};
assign aux_dat_io = (aux_we_reg && clk_en_i)?aluout:{8{1'bZ}};
assign aux_we_o   = aux_we_reg;

endmodule


//`undef STATEBIT_SIZE

⌨️ 快捷键说明

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