📄 piccore.v
字号:
end if (stack_pos_node[4] == 1'b1) begin stack_cell[4] = stack4_node; end else begin stack_cell[4] = 13'b0000000000000; end if (stack_pos_node[5] == 1'b1) begin stack_cell[5] = stack5_node; end else begin stack_cell[5] = 13'b0000000000000; end if (stack_pos_node[6] == 1'b1) begin stack_cell[6] = stack6_node; end else begin stack_cell[6] = 13'b0000000000000; end if (stack_pos_node[7] == 1'b1) begin stack_cell[7] = stack7_node; end else begin stack_cell[7] = 13'b0000000000000; end top = stack_cell[0]; top = top | stack_cell[1]; top = top | stack_cell[2]; top = top | stack_cell[3]; top = top | stack_cell[4]; top = top | stack_cell[5]; top = top | stack_cell[6]; top = top | stack_cell[7]; stacktop_node <= top; end// MAIN EFSM: description of register value changes in each clock cycle // Intermidiate nodes used for resource sharing reg [7:0] ramin_node; // result of reading RAM/Special registers reg [12:0] incpc_node; // value of PC + 1 reg [7:0] mask_node; // bit mask for logical operations reg [8:0] add_node; // result of 8bit addition (std_logic_vector) reg [4:0] addLow_node; // reulst of low-4bit addition (std_logic_vector) reg aluout_zero_node; // H if ALUOUT = 0 reg writew_node; // H if destination is W register reg writeram_node; // H if destination is RAM/Special registers reg int_node; // H if interrupt request comes reg wdtreset_node; // H if WDT-reset request comes reg reset_cond; // H if any reset request comes (jump to Qreset state)// >> added on Dec 10,2000 reg [2:0] stack_full_node;// << added on Dec 10,2000//> added ver1.00c, 2002/08/07 reg extbit_node;//< always @(posedge clkin) begin // 1. Intermidiate nodes for resource sharing // 1-1. Result of reading RAM; one of data sources (see pp.13 of PIC16F84 data sheet) if (ADDR_SRAM == 1'b1) begin ramin_node = ramdtin; // data bus output of external SRAM end else if (ADDR_EEDATA == 1'b1) begin ramin_node = eedata_reg; // data bus output of external EEPROM end else if (ADDR_TMR0 == 1'b1) begin ramin_node = tmr0_reg; // TMR0 end else if (ADDR_PCL == 1'b1) begin ramin_node = pc_reg[7:0]; // PCL end else if (ADDR_STAT == 1'b1) begin ramin_node = status_reg; // STATUS end else if (ADDR_FSR == 1'b1) begin ramin_node = fsr_reg; // FSR end else if (ADDR_PORTA == 1'b1) begin if (trisa_reg[0] == 1'b1) begin ramin_node[0] = portain_sync_reg[0]; // PORT B (when input mode) end else begin ramin_node[0] = portaout_reg[0]; // PORT B (when output mode) end if (trisa_reg[1] == 1'b1) begin ramin_node[1] = portain_sync_reg[1]; end else begin ramin_node[1] = portaout_reg[1]; end if (trisa_reg[2] == 1'b1) begin ramin_node[2] = portain_sync_reg[2]; end else begin ramin_node[2] = portaout_reg[2]; end if (trisa_reg[3] == 1'b1) begin ramin_node[3] = portain_sync_reg[3]; end else begin ramin_node[3] = portaout_reg[3]; end if (trisa_reg[4] == 1'b1) begin ramin_node[4] = portain_sync_reg[4]; end else begin ramin_node[4] = portaout_reg[4]; end ramin_node[7:5] = 3'b000; end else if (ADDR_PORTB == 1'b1) begin if (trisb_reg[0] == 1'b1) begin ramin_node[0] = portbin_sync_reg[0]; // PORT B (when input mode) end else begin ramin_node[0] = portbout_reg[0]; // PORT B (when output mode) end if (trisb_reg[1] == 1'b1) begin ramin_node[1] = portbin_sync_reg[1]; end else begin ramin_node[1] = portbout_reg[1]; end if (trisb_reg[2] == 1'b1) begin ramin_node[2] = portbin_sync_reg[2]; end else begin ramin_node[2] = portbout_reg[2]; end if (trisb_reg[3] == 1'b1) begin ramin_node[3] = portbin_sync_reg[3]; end else begin ramin_node[3] = portbout_reg[3]; end if (trisb_reg[4] == 1'b1) begin ramin_node[4] = portbin_sync_reg[4]; end else begin ramin_node[4] = portbout_reg[4]; end if (trisb_reg[5] == 1'b1) begin ramin_node[5] = portbin_sync_reg[5]; end else begin ramin_node[5] = portbout_reg[5]; end if (trisb_reg[6] == 1'b1) begin ramin_node[6] = portbin_sync_reg[6]; end else begin ramin_node[6] = portbout_reg[6]; end if (trisb_reg[7] == 1'b1) begin ramin_node[7] = portbin_sync_reg[7]; end else begin ramin_node[7] = portbout_reg[7]; end end else if (ADDR_EEADR == 1'b1) begin ramin_node = eeadr_reg; // EEADR end else if (ADDR_PCLATH == 1'b1) begin ramin_node = {3'b000, pclath_reg}; // PCLATH (5bit) end else if (ADDR_INTCON == 1'b1) begin ramin_node = intcon_reg; // INTCON end else if (ADDR_OPTION == 1'b1) begin ramin_node = option_reg; // OPTION end else if (ADDR_TRISA == 1'b1) begin ramin_node = {3'b000, trisa_reg}; // TRISA end else if (ADDR_TRISB == 1'b1) begin ramin_node = trisb_reg; // TRISB end else if (ADDR_EECON1 == 1'b1) begin ramin_node = {3'b000, eecon1_reg}; // EECON1 (5bit) end else begin ramin_node = {8{1'b0}}; end // 1-2. PC + 1 incpc_node = pc_reg + 13'b0000000000001; // 1-3. Adder (ALU)//> changed ver1.00c, 2002/08/07 // full 8bit-addtion // add_node = {1'b0,aluinp1_reg} + {1'b0,aluinp2_reg}; add_node = ({1'b0, aluinp1_reg}) + aluinp2_reg; // lower 4bit-addtion if (INST_SUBLW == 1'b1 || INST_SUBWF == 1'b1) begin extbit_node = aluinp2_reg[4]; end else begin extbit_node = 1'b0; end // addLow_node = {1'b0,aluinp1_reg[3:0]} + {1'b0,aluinp2_reg[3:0]}; addLow_node = ({1'b0, aluinp1_reg[3:0]}) + ({extbit_node, aluinp2_reg[3:0]});//< // 1-4. Test if aluout = 0 if (aluout_reg == 8'b00000000) begin aluout_zero_node = 1'b1; end else begin aluout_zero_node = 1'b0; end // 1-5. Determine destination if (intstart_reg == 1'b1) begin writew_node = 1'b0; writeram_node = 1'b0; end else if (INST_MOVWF == 1'b1 || INST_BCF == 1'b1 || INST_BSF == 1'b1 || INST_CLRF == 1'b1) begin writew_node = 1'b0; writeram_node = 1'b1; end else if (INST_MOVLW == 1'b1 || INST_ADDLW == 1'b1 || INST_SUBLW == 1'b1 || INST_ANDLW == 1'b1 || INST_IORLW == 1'b1 || INST_XORLW == 1'b1 || INST_RETLW == 1'b1 || INST_CLRW == 1'b1) begin writew_node = 1'b1; writeram_node = 1'b0; end else if (INST_MOVF == 1'b1 || INST_SWAPF == 1'b1 || INST_ADDWF == 1'b1 || INST_SUBWF == 1'b1 || INST_ANDWF == 1'b1 || INST_IORWF == 1'b1 || INST_XORWF == 1'b1 || INST_DECF == 1'b1 || INST_INCF == 1'b1 || INST_RLF == 1'b1 || INST_RRF == 1'b1 || INST_DECFSZ == 1'b1 || INST_INCFSZ == 1'b1 || INST_COMF == 1'b1) begin writew_node = ~inst_reg[7]; // ("d" field of fetched instruction) writeram_node = inst_reg[7]; // ("d" field of fetched instruction) end else begin writew_node = 1'b0; writeram_node = 1'b0; end // 1-6. Interrupt request (see pp.17 of PIC16F84 data sheet) int_node = intcon_reg[7] // GIE & ((intcon_reg[3] & intcon_reg[0]) // RBIE and RBIF | (intcon_reg[4] & intcon_reg[1]) // INTE and INTF | (intcon_reg[5] & intcon_reg[2]) // T0IE and T0IF | (intcon_reg[6] & eecon1_reg[4])); // EEIE and EEIF(EECON1) // 1-7. Reset conditions wdtreset_node = wdt_full_sync_reg[1] & ( ~wdt_full_sync_reg[2]); // WDT if (poweron_sync_reg == 1'b0 || mclr_sync_reg == 1'b0 || wdtreset_node == 1'b1) begin // (all of reset triggers) reset_cond = 1'b1; end else begin reset_cond = 1'b0; end // 2. EFSM body case (state_reg) // 2-1. Reset state (see pp.14 and pp.42 of PIC16F84 data sheet) Qreset: begin pc_reg <= {13{1'b0}}; // 0 status_reg[7:5] <= 3'b000; pclath_reg <= {5{1'b0}}; // 0 intcon_reg[7:1] <= 7'b0000000; option_reg <= {8{1'b1}}; trisa_reg <= {5{1'b1}}; trisb_reg <= {8{1'b1}}; tmr0_reg <= {8{1'b0}}; // (specification: don't care) exec_op_reg <= 1'b0; intclr_reg <= {5{1'b1}}; // clear int intstart_reg <= 1'b0; writeram_reg <= 1'b0; sleepflag_reg <= 1'b0; // (set /T0 and /PD properly; see pp.42 and pp.46 of data sheet) if (poweron_sync_reg == 1'b0) begin // Power-on Reset status_reg[4] <= 1'b1; // /T0 = 1 status_reg[3] <= 1'b1; // /PD = 1 end else if (mclr_sync_reg == 1'b0) begin // MCLR reset/MCLR wake up from sleep status_reg[4] <= 1'b1; // /T0 = 1 status_reg[3] <= ~sleepflag_reg; // /PD = 1 if normal reset, /PD = 0 if wake up end else if (wdtreset_node == 1'b1) begin // WDT reset/WDT wake up from sleep status_reg[4] <= 1'b0; // /T0 = 0 status_reg[3] <= ~sleepflag_reg; // /PD = 1 if normal reset, /PD = 0 if wake up end eecon1_reg[4] <= 1'b0; // (set WRERR bit in EECON1 properly; see pp.33 and pp.34 of data sheet) if (poweron_sync_reg == 1'b0) begin eecon1_reg[3] <= 1'b0; // clear WRERR end else begin eecon1_reg[3] <= eecon1_reg[1]; // substitute WR into WRERR end eecon1_reg[2:0] <= 3'b000; if (poweron_sync_reg == 1'b0) begin // NOTICE: do NOT clear stack pointer for MCLR reset or WDT reset (the value must be hold) stack_pnt_reg <= 0; end if (reset_cond == 1'b0) begin // go to Q1 if reset signal is disasserted. state_reg <= Q1; end end // 2-2. Q1 cycle Q1: begin // 2-2-1. Clear external interrupt registers if GIE=0 if (intcon_reg[7] == 1'b1) begin intclr_reg <= {5{1'b0}}; end else begin // GIE = 0 intclr_reg <= {5{1'b1}}; // clear interrupt end // 2-2-2. Read I/O port portain_sync_reg <= porta_in; portbin_sync_reg <= portb_in; // 2-2-3. Read/Write EEPROM, if necessary if (intstart_reg == 1'b0) begin if (eecon1_reg[0] == 1'b1 && rdeep_sync_reg == 1'b1) begin // reading EEPROM complete eedata_reg <= eepdtin; eecon1_reg[0] <= 1'b0; // clear EECON1_RD end if (eecon1_reg[1] == 1'b1 && wreep_sync_reg == 1'b1) begin // writing EEPROM complete if (intcon_reg[7] == 1'b1 && intcon_reg[6] == 1'b1) begin eecon1_reg[4] <= 1'b1; // INT (EE write complete) end eecon1_reg[1] <= 1'b0; // clear EECON1_WR end//> deleted ver1.00c, 2002/08/07// if (exec_op_reg == 1'b1) begin// ramadr_reg <= ramadr_node; // RAM read address// end//< end // 2-2-4. Check increment-TMR0 request if (inctmr_sync_reg == 2'b01) begin inctmrhold_reg <= 1'b1; end // 2-2-5. Goto next cycle if (reset_cond == 1'b1) begin state_reg <= Qreset; end else begin // if in the sleep mode, wait until wake-up triggers comes if (sleepflag_reg == 1'b1 && intstart_reg == 1'b0) begin if (inte_sync_reg == 1'b1 || rbint_sync_reg == 1'b1) begin // if PORT-B interrupts come, then resume execution // otherwise, if WDT reset/MCLR reset come, then goto Qreset sleepflag_reg <= 1'b0; state_reg <= Q2; end end else begin state_reg <= Q2; end end end // 2-3. Q2 cycle Q2: begin // 2-3-1. Read data-RAM and substitute source values to alu-input registers if (exec_op_reg == 1'b1 && intstart_reg == 1'b0) begin // if NOT STALLED // 2-3-1-1. Set aluinp1 register (source #1) if (INST_MOVF == 1'b1 || INST_SWAPF == 1'b1 || INST_ADDWF == 1'b1 || INST_SUBWF == 1'b1 || INST_ANDWF == 1'b1 || INST_IORWF == 1'b1 || INST_XORWF == 1'b1 || INST_DECF == 1'b1 || INST_INCF == 1'b1 || INST_RLF == 1'b1 || INST_RRF == 1'b1 || INST_BCF == 1'b1 || INST_BSF == 1'b1 || INST_BTFSC == 1'b1 || INST_BTFSS == 1'b1 || INST_DECFSZ == 1'b1 || INST_INCFSZ == 1'b1 || INST_COMF == 1'b1) begin aluinp1_reg <= ramin_node; // RAM/Special registers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -