📄 piccore.vhd
字号:
writeram_reg <= '0'; -- 2-5-4. Change clkout output clkout_reg <= '0'; -- 2-5-5. Check increment-TMR0 request if (inctmr_sync_reg = "01") then inctmrhold_reg <= '1'; end if; -- 2-5-6. Goto next cycle if (reset_cond = '1') then state_reg <= Qreset; else state_reg <= Q1; end if; -- 2-6. Illegal states (NEVER REACHED in normal execution) when others => state_reg <= Qreset; -- goto reset state end case; end if; end process;-- TMR0 pre-scaler (see pp.27 of PIC16F84 data sheet) -- select pre-scaler psck <= clkout_reg when option_reg(5) = '0' else -- option_reg(5):T0CS t0cki xor option_reg(4); -- option_reg(4):T0SE -- pre-scaler body u3:process (psck, ponrst_n) variable rateval : integer range 0 to 255; begin if (ponrst_n = '0') then pscale_reg <= 0; ps_full_reg <= '0'; elsif (psck'event and psck = '1') then case option_reg(2 downto 0) is -- select prescaler-full value by PS2-0 when "000" => rateval := 1; when "001" => rateval := 3; when "010" => rateval := 7; when "011" => rateval := 15; when "100" => rateval := 31; when "101" => rateval := 63; when "110" => rateval := 127;-- when "111" => rateval := 255; when others => rateval := 255; end case; if (pscale_reg >= rateval) then pscale_reg <= 0; ps_full_reg <= '1'; else pscale_reg <= pscale_reg + 1; ps_full_reg <= '0'; end if; end if; end process; -- select TMR0-increment trigger inctmrck <= psck when option_reg(3) = '1' else -- option_reg(3):PSA ps_full_reg; -- ps_full_reg:output of pre-scaler-- WDT timer body u4:process (wdtclk, ponrst_n, mclr_n) variable wdtfull_node : std_logic; begin if (ponrst_n = '0' or mclr_n = '0') then -- (async reset) wdt_reg <= 0; wdt_full_reg <= '0'; wdtclr_req_reg <= "00"; wdtfullclr_req_reg <= "00"; elsif (wdtclk'event and wdtclk = '1') then -- synchronizers -- WDT-clear request (CLRWDT/SLEEP instruction) wdtclr_req_reg(0) <= wdt_clr_reg; -- (do not AND with sleepflag_reg, since WDT should be cleared at SLEEP instruction) wdtclr_req_reg(1) <= wdtclr_req_reg(0); -- WDT-full-clear request (after WDT reset) wdtfullclr_req_reg(0) <= wdtfull_clr_reg and (not sleepflag_reg); wdtfullclr_req_reg(1) <= wdtfullclr_req_reg(0); -- timer/full reg if (wdt_reg >= WDT_SIZE) then wdtfull_node := '1'; -- (intermidiate node) else wdtfull_node := '0'; -- (intermidiate node) end if; -- wdt_reg(counter) body if (wdtclr_req_reg = "01" or wdtena = '0') then wdt_reg <= 0; elsif (wdtfull_node = '1') then wdt_reg <= 0; else wdt_reg <= wdt_reg + 1; end if; -- wdt_full_reg(interrupt trigger) body if (wdtfullclr_req_reg = "01" or wdtena = '0') then wdt_full_reg <= '0'; elsif (wdtfull_node = '1') then wdt_full_reg <= '1'; end if; end if; end process; wdtclr_ack <= wdtclr_req_reg(1); -- WDT-clear ack signal to CPU wdtfull <= wdt_full_reg; -- WDT-full signal (interrupt trigger) to CPU-- WDT controller in CPU-clock line (handshake-interface between WDT and CPU-EFSM) u5:process (clkin) begin if (clkin'event and clkin = '1') then if (poweron_sync_reg = '0' or mclr_sync_reg = '0') then wdt_clr_reg <= '0'; -- WDT clear request register wdt_clr_reqhold_reg <= '0'; -- will be 1 when WDT clear request comes while another clear request is still processed wdtfull_clr_reg <= '0'; -- WDT-full clear request register else -- WDT-clear/hold WDT-clear request -- (handshake) if (wdt_clr_reg = '1') then -- still processing clear-operation if (wdtclr_ack_sync_reg = '1') then -- if ack comes, go down the clear request wdt_clr_reg <= '0'; end if; elsif (wdt_clr_reqhold_reg = '1' or (state_reg = Q4 and exec_op_reg = '1' and intstart_reg = '0' and (INST_CLRWDT = '1' or INST_SLEEP = '1')) ) then -- clear request comes if (wdtclr_ack_sync_reg = '0') then -- confirm if ack is 0 wdt_clr_reg <= '1'; wdt_clr_reqhold_reg <= '0'; else -- (wait until ack becomes 0) wdt_clr_reqhold_reg <= '1'; end if; end if; -- clear WDT-full (CPU reset request) -- (handshake) if (wdtfull_clr_reg = '1') then -- still processing clear-operation if (wdt_full_sync_reg(1) = '0') then -- if ack comes, go down the clear request wdtfull_clr_reg <= '0'; end if; elsif (wdt_full_sync_reg(1) = '1') then -- clear request comes -- the WDT-full signal does not come so often, so hold-register is not necessary wdtfull_clr_reg <= '1'; end if; end if; end if; end process;-- Detect external interrupt requests -- INT0 I/F u6:process (int0, intclr_reg) begin if (intclr_reg(0) = '1') then intrise_reg(0) <= '0'; elsif (int0'event and int0 = '1') then -- catch positive edge intrise_reg(0) <= '1'; end if; end process; u7:process (int0, intclr_reg) begin if (intclr_reg(0) = '1') then intdown_reg(0) <= '0'; elsif (int0'event and int0 = '0') then -- catch negative edge intdown_reg(0) <= '1'; end if; end process; rb0_int <= intrise_reg(0) when option_reg(6) = '1' else -- option_reg(6):INTEDG intdown_reg(0); -- INT4 I/F u8:process (int4, intclr_reg) begin if (intclr_reg(1) = '1') then intrise_reg(1) <= '0'; elsif (int4'event and int4 = '1') then -- catch positive edge intrise_reg(1) <= '1'; end if; end process; u9:process (int4, intclr_reg) begin if (intclr_reg(1) = '1') then intdown_reg(1) <= '0'; elsif (int4'event and int4 = '0') then -- catch negative edge intdown_reg(1) <= '1'; end if; end process; rb4_int <= intrise_reg(1) or intdown_reg(1); -- INT5 I/F u10:process (int5, intclr_reg) begin if (intclr_reg(2) = '1') then intrise_reg(2) <= '0'; elsif (int5'event and int5 = '1') then -- catch positive edge intrise_reg(2) <= '1'; end if; end process; u11:process (int5, intclr_reg) begin if (intclr_reg(2) = '1') then intdown_reg(2) <= '0'; elsif (int5'event and int5 = '0') then -- catch negative edge intdown_reg(2) <= '1'; end if; end process; rb5_int <= intrise_reg(2) or intdown_reg(2); -- INT6 I/F u12:process (int6, intclr_reg) begin if (intclr_reg(3) = '1') then intrise_reg(3) <= '0'; elsif (int6'event and int6 = '1') then -- catch positive edge intrise_reg(3) <= '1'; end if; end process; u13:process (int6, intclr_reg) begin if (intclr_reg(3) = '1') then intdown_reg(3) <= '0'; elsif (int6'event and int6 = '0') then -- catch negative edge intdown_reg(3) <= '1'; end if; end process; rb6_int <= intrise_reg(3) or intdown_reg(3); -- INT7 I/F u14:process (int7, intclr_reg) begin if (intclr_reg(4) = '1') then intrise_reg(4) <= '0'; elsif (int7'event and int7 = '1') then -- catch positive edge intrise_reg(4) <= '1'; end if; end process; u15:process (int7, intclr_reg) begin if (intclr_reg(4) = '1') then intdown_reg(4) <= '0'; elsif (int7'event and int7 = '0') then -- catch negative edge intdown_reg(4) <= '1'; end if; end process; rb7_int <= intrise_reg(4) or intdown_reg(4);-- Decode INT triggers (do not AND with GIE(intcon_reg(7)), since these signals are also used for waking up from SLEEP) inte <= intcon_reg(4) and rb0_int; -- G0IE and raw-trigger signal rbint <= intcon_reg(3) and (rb4_int or rb5_int or rb6_int or rb7_int); -- RBIE and raw-trigger signal-- Circuit's output siganals progadr <= pc_reg; -- program ROM address--> modified ver1.00c, 2002/08/07-- ramadr <= ramadr_reg; -- data RAM address -- map 0F0-0FF,170-17F, and 1F0-1FF into 070-07F ramadr <= ramadr_node when ramadr_node(6 downto 4) /= "111" else "00111" & ramadr_node(3 downto 0); -- data RAM address--< ramdtout <= aluout_reg; -- data RAM write data--> modified ver1.00c, 2002/08/07-- readram <= '1' when state_reg(1 downto 0) = "01" else '0'; -- data RAM read enable (1 when state_reg = Q2) readram <= not writeram_reg;--< writeram <= writeram_reg; -- data RAM write enable eepadr <= eeadr_reg; -- EEPROM address eepdtout <= eedata_reg; -- EEPROM write data readeepreq <= eecon1_reg(0); -- EEPROM read request writeeepreq <= eecon1_reg(1); -- EEPROM write request porta_out <= portaout_reg; -- PORT-A output porta_dir <= trisa_reg; -- PORT-A direction portb_out <= portbout_reg; -- PORT-B output portb_dir <= trisb_reg; -- PORT-B direction rbpu <= option_reg(7); -- RBPU: pull-up enable clkout <= clkout_reg; -- clkout (clkin/4) output powerdown <= sleepflag_reg; -- CPU clock stop indicator startclkin <= inte or rbint or wdt_full_reg or (not mclr_n) or (not ponrst_n); -- CPU clock start indicatorend RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -