URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/open8_urisc/trunk/VHDL
- from Rev 210 to Rev 209
- ↔ Reverse comparison
Rev 210 → Rev 209
/o8_cpu.vhd
194,14 → 194,6
-- only the core ALU flags (Z, N, and C). Also |
-- brought out copies of the GP flags for external |
-- connection. |
-- Seth Henry 04/09/20 Added a compile time setting to block interrupts |
-- while the I bit is set to avoid reentering ISRs |
-- This may slightly affect timing, as this will |
-- potentially block higher priority interrupts |
-- until the lower priority ISR returns or clears |
-- the I bit. |
-- Also added the I bit to the exported flags for |
-- use in memory protection schemes. |
|
library ieee; |
use ieee.std_logic_1164.all; |
222,7 → 214,6
Enable_Auto_Increment : boolean := false; -- Modify indexed instr |
BRK_Implements_WAI : boolean := false; -- BRK -> Wait for Int |
Enable_NMI : boolean := true; -- Force INTR0 enabled |
Sequential_Interrupts : boolean := false; -- Interruptable ISRs |
RTI_Ignores_GP_Flags : boolean := false; -- RTI restores all flags |
Default_Interrupt_Mask : DATA_TYPE := x"FF"; -- Enable all Ints |
Reset_Level : std_logic := '0' ); -- Active reset level |
287,7 → 278,6
signal i_Ints : INTERRUPT_BUNDLE := x"00"; |
signal Pending : INTERRUPT_BUNDLE := x"00"; |
signal Wait_for_FSM : std_logic := '0'; |
signal Wait_for_ISR : std_logic := '0'; |
|
begin |
|
905,7 → 895,6
Int_Req <= '0'; |
Pending <= x"00"; |
Wait_for_FSM <= '0'; |
Wait_for_ISR <= '0'; |
if( Enable_NMI )then |
Int_Mask <= Default_Interrupt_Mask(7 downto 1) & '1'; |
else |
918,7 → 907,7
end loop; |
Flags <= x"00"; |
|
GP_Flags <= (others => '0'); |
GP_Flags <= x"0"; |
|
elsif( rising_edge(Clock) )then |
|
1047,13 → 1036,7
|
Pending <= i_Ints or Pending; |
|
if( Sequential_Interrupts )then |
Wait_for_ISR <= Flags(PSR_I); |
else |
Wait_for_ISR <= '0'; |
end if; |
|
if( Wait_for_FSM = '0' and Wait_for_ISR = '0' )then |
if( Wait_for_FSM = '0' )then |
if( Pending(0) = '1' )then |
ISR_Addr <= INT_VECTOR_0; |
Pending(0) <= '0'; |
1255,7 → 1238,7
null; |
end case; |
|
GP_Flags <= Flags(7 downto 3); |
GP_Flags <= Flags(7 downto 4); |
|
end if; |
end process; |
/o8_rtc.vhd
52,48 → 52,48
|
entity o8_rtc is |
generic( |
Sys_Freq : real; |
Reset_Level : std_logic; |
Address : ADDRESS_TYPE |
Sys_Freq : real; |
Reset_Level : std_logic; |
Address : ADDRESS_TYPE |
); |
port( |
Clock : in std_logic; |
Reset : in std_logic; |
uSec_Tick : out std_logic; |
Clock : in std_logic; |
Reset : in std_logic; |
uSec_Tick : out std_logic; |
-- |
Bus_Address : in ADDRESS_TYPE; |
Wr_Enable : in std_logic; |
Wr_Data : in DATA_TYPE; |
Rd_Enable : in std_logic; |
Rd_Data : out DATA_TYPE; |
Bus_Address : in ADDRESS_TYPE; |
Wr_Enable : in std_logic; |
Wr_Data : in DATA_TYPE; |
Rd_Enable : in std_logic; |
Rd_Data : out DATA_TYPE; |
-- |
Interrupt_PIT : out std_logic; |
Interrupt_RTC : out std_logic |
Interrupt_PIT : out std_logic; |
Interrupt_RTC : out std_logic |
); |
end entity; |
|
architecture behave of o8_rtc is |
|
constant User_Addr : std_logic_vector(15 downto 3) |
:= Address(15 downto 3); |
alias Comp_Addr is Bus_Address(15 downto 3); |
signal Addr_Match : std_logic; |
constant User_Addr : std_logic_vector(15 downto 3) |
:= Address(15 downto 3); |
alias Comp_Addr is Bus_Address(15 downto 3); |
signal Addr_Match : std_logic; |
|
alias Reg_Addr is Bus_Address(2 downto 0); |
signal Reg_Addr_q : std_logic_vector(2 downto 0); |
alias Reg_Addr is Bus_Address(2 downto 0); |
signal Reg_Addr_q : std_logic_vector(2 downto 0); |
|
signal Wr_En : std_logic; |
signal Wr_Data_q : DATA_TYPE; |
signal Rd_En : std_logic; |
signal Wr_En : std_logic; |
signal Wr_Data_q : DATA_TYPE; |
signal Rd_En : std_logic; |
|
constant DLY_1USEC_VAL : integer := integer(Sys_Freq / 1000000.0); |
constant DLY_1USEC_WDT : integer := ceil_log2(DLY_1USEC_VAL - 1); |
constant DLY_1USEC : std_logic_vector := |
conv_std_logic_vector( DLY_1USEC_VAL - 1, DLY_1USEC_WDT); |
constant DLY_1USEC_VAL: integer := integer(Sys_Freq / 1000000.0); |
constant DLY_1USEC_WDT: integer := ceil_log2(DLY_1USEC_VAL - 1); |
constant DLY_1USEC : std_logic_vector := |
conv_std_logic_vector( DLY_1USEC_VAL - 1, DLY_1USEC_WDT); |
|
signal uSec_Cntr : std_logic_vector( DLY_1USEC_WDT - 1 downto 0 ) |
:= (others => '0'); |
signal uSec_Tick_i : std_logic; |
signal uSec_Cntr : std_logic_vector( DLY_1USEC_WDT - 1 downto 0 ) |
:= (others => '0'); |
signal uSec_Tick_i : std_logic; |
|
type PIT_TYPE is record |
timer_cnt : DATA_TYPE; |
139,8 → 139,7
signal rtc : RTC_TYPE; |
|
signal interval : DATA_TYPE; |
signal update_interval: std_logic; |
signal new_interval : DATA_TYPE; |
signal mask_pit_int : std_logic; |
|
signal shd_tens : DATA_TYPE; |
signal shd_secs : DATA_TYPE; |
154,230 → 153,228
|
begin |
|
uSec_Tick <= uSec_Tick_i; |
Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; |
uSec_Tick <= uSec_Tick_i; |
Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; |
|
Interrupt_PIT <= pit.timer_ro; |
Interrupt_RTC <= rtc.frac_ro; |
Interrupt_PIT <= pit.timer_ro; |
Interrupt_RTC <= rtc.frac_ro; |
|
io_reg: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
uSec_Cntr <= (others => '0'); |
uSec_Tick_i <= '0'; |
uSec_Cntr <= (others => '0'); |
uSec_Tick_i <= '0'; |
|
pit.timer_cnt <= x"00"; |
pit.timer_ro <= '0'; |
pit.timer_cnt <= x"00"; |
pit.timer_ro <= '0'; |
|
rtc.frac <= DECISEC; |
rtc.frac_ro <= '0'; |
rtc.frac <= DECISEC; |
rtc.frac_ro <= '0'; |
|
rtc.tens_l <= (others => '0'); |
rtc.tens_l_ro <= '0'; |
rtc.tens_l <= (others => '0'); |
rtc.tens_l_ro <= '0'; |
|
rtc.tens_u <= (others => '0'); |
rtc.tens_u_ro <= '0'; |
rtc.tens_u <= (others => '0'); |
rtc.tens_u_ro <= '0'; |
|
rtc.secs_l <= (others => '0'); |
rtc.secs_l_ro <= '0'; |
rtc.secs_l <= (others => '0'); |
rtc.secs_l_ro <= '0'; |
|
rtc.secs_u <= (others => '0'); |
rtc.secs_u_ro <= '0'; |
rtc.secs_u <= (others => '0'); |
rtc.secs_u_ro <= '0'; |
|
rtc.mins_l <= (others => '0'); |
rtc.mins_l_ro <= '0'; |
rtc.mins_l <= (others => '0'); |
rtc.mins_l_ro <= '0'; |
|
rtc.mins_u <= (others => '0'); |
rtc.mins_u_ro <= '0'; |
rtc.mins_u <= (others => '0'); |
rtc.mins_u_ro <= '0'; |
|
rtc.hours_l <= (others => '0'); |
rtc.hours_l_ro <= '0'; |
rtc.hours_l <= (others => '0'); |
rtc.hours_l_ro <= '0'; |
|
rtc.hours_u <= (others => '0'); |
rtc.hours_u_ro <= '0'; |
rtc.hours_u <= (others => '0'); |
rtc.hours_u_ro <= '0'; |
|
rtc.dow <= (others => '0'); |
rtc.dow <= (others => '0'); |
|
shd_tens <= (others => '0'); |
shd_secs <= (others => '0'); |
shd_mins <= (others => '0'); |
shd_hours <= (others => '0'); |
shd_dow <= (others => '0'); |
shd_tens <= (others => '0'); |
shd_secs <= (others => '0'); |
shd_mins <= (others => '0'); |
shd_hours <= (others => '0'); |
shd_dow <= (others => '0'); |
|
update_rtc <= '0'; |
update_shd <= '0'; |
update_ctmr <= (others => '0'); |
update_rtc <= '0'; |
update_shd <= '0'; |
update_ctmr <= (others => '0'); |
|
interval <= x"00"; |
update_interval <= '0'; |
new_interval <= x"00"; |
interval <= x"00"; |
mask_pit_int <= '0'; |
|
Wr_Data_q <= (others => '0'); |
Reg_Addr_q <= (others => '0'); |
Wr_En <= '0'; |
Rd_En <= '0'; |
Rd_Data <= OPEN8_NULLBUS; |
Wr_Data_q <= (others => '0'); |
Reg_Addr_q <= (others => '0'); |
Wr_En <= '0'; |
Rd_En <= '0'; |
Rd_Data <= OPEN8_NULLBUS; |
|
elsif( rising_edge( Clock ) )then |
|
uSec_Cntr <= uSec_Cntr - 1; |
uSec_Tick_i <= '0'; |
uSec_Cntr <= uSec_Cntr - 1; |
uSec_Tick_i <= '0'; |
if( uSec_Cntr = 0 )then |
uSec_Cntr <= DLY_1USEC; |
uSec_Tick_i <= '1'; |
uSec_Cntr <= DLY_1USEC; |
uSec_Tick_i <= '1'; |
end if; |
|
-- Periodic Interval Timer |
pit.timer_cnt <= pit.timer_cnt - uSec_Tick_i; |
pit.timer_ro <= '0'; |
if( update_interval = '1' )then |
pit.timer_cnt <= new_interval; |
elsif( or_reduce(pit.timer_cnt) = '0' )then |
pit.timer_cnt <= interval; |
pit.timer_ro <= or_reduce(interval); |
|
pit.timer_cnt <= pit.timer_cnt - uSec_Tick_i; |
pit.timer_ro <= '0'; |
if( or_reduce(pit.timer_cnt) = '0' )then |
pit.timer_cnt <= interval; |
pit.timer_ro <= or_reduce(interval) and -- Only issue output on Int > 0 |
(not mask_pit_int); -- and we didn't just update it |
|
end if; |
|
-- Fractional decisecond counter - cycles every 10k microseconds |
rtc.frac <= rtc.frac - uSec_Tick_i; |
rtc.frac_ro <= '0'; |
rtc.frac <= rtc.frac - uSec_Tick_i; |
rtc.frac_ro <= '0'; |
if( or_reduce(rtc.frac) = '0' or update_rtc = '1' )then |
rtc.frac <= DECISEC; |
rtc.frac_ro <= not update_rtc; |
rtc.frac <= DECISEC; |
rtc.frac_ro <= not update_rtc; |
end if; |
|
-- Decisecond counter (lower) |
rtc.tens_l <= rtc.tens_l + rtc.frac_ro; |
rtc.tens_l_ro <= '0'; |
rtc.tens_l <= rtc.tens_l + rtc.frac_ro; |
rtc.tens_l_ro <= '0'; |
if( update_rtc = '1' )then |
rtc.tens_l <= shd_tens(3 downto 0); |
rtc.tens_l <= shd_tens(3 downto 0); |
elsif( rtc.tens_l > x"9")then |
rtc.tens_l <= (others => '0'); |
rtc.tens_l_ro <= '1'; |
rtc.tens_l <= (others => '0'); |
rtc.tens_l_ro <= '1'; |
end if; |
|
-- Decisecond counter (upper) |
rtc.tens_u <= rtc.tens_u + rtc.tens_l_ro; |
rtc.tens_u_ro <= '0'; |
rtc.tens_u <= rtc.tens_u + rtc.tens_l_ro; |
rtc.tens_u_ro <= '0'; |
if( update_rtc = '1' )then |
rtc.tens_u <= shd_tens(7 downto 4); |
rtc.tens_u <= shd_tens(7 downto 4); |
elsif( rtc.tens_u > x"9")then |
rtc.tens_u <= (others => '0'); |
rtc.tens_u_ro <= '1'; |
rtc.tens_u <= (others => '0'); |
rtc.tens_u_ro <= '1'; |
end if; |
|
-- Second counter (lower) |
rtc.secs_l <= rtc.secs_l + rtc.tens_u_ro; |
rtc.secs_l_ro <= '0'; |
rtc.secs_l <= rtc.secs_l + rtc.tens_u_ro; |
rtc.secs_l_ro <= '0'; |
if( update_rtc = '1' )then |
rtc.secs_l <= shd_secs(3 downto 0); |
rtc.secs_l <= shd_secs(3 downto 0); |
elsif( rtc.secs_l > x"9")then |
rtc.secs_l <= (others => '0'); |
rtc.secs_l_ro <= '1'; |
rtc.secs_l <= (others => '0'); |
rtc.secs_l_ro <= '1'; |
end if; |
|
-- Second counter (upper) |
rtc.secs_u <= rtc.secs_u + rtc.secs_l_ro; |
rtc.secs_u_ro <= '0'; |
rtc.secs_u <= rtc.secs_u + rtc.secs_l_ro; |
rtc.secs_u_ro <= '0'; |
if( update_rtc = '1' )then |
rtc.secs_u <= shd_secs(7 downto 4); |
rtc.secs_u <= shd_secs(7 downto 4); |
elsif( rtc.secs_u > x"5")then |
rtc.secs_u <= (others => '0'); |
rtc.secs_u_ro <= '1'; |
rtc.secs_u <= (others => '0'); |
rtc.secs_u_ro <= '1'; |
end if; |
|
-- Minutes counter (lower) |
rtc.mins_l <= rtc.mins_l + rtc.secs_u_ro; |
rtc.mins_l_ro <= '0'; |
rtc.mins_l <= rtc.mins_l + rtc.secs_u_ro; |
rtc.mins_l_ro <= '0'; |
if( update_rtc = '1' )then |
rtc.mins_l <= shd_mins(3 downto 0); |
rtc.mins_l <= shd_mins(3 downto 0); |
elsif( rtc.mins_l > x"9")then |
rtc.mins_l <= (others => '0'); |
rtc.mins_l_ro <= '1'; |
rtc.mins_l <= (others => '0'); |
rtc.mins_l_ro <= '1'; |
end if; |
|
-- Minutes counter (upper) |
rtc.mins_u <= rtc.mins_u + rtc.mins_l_ro; |
rtc.mins_u_ro <= '0'; |
rtc.mins_u <= rtc.mins_u + rtc.mins_l_ro; |
rtc.mins_u_ro <= '0'; |
if( update_rtc = '1' )then |
rtc.mins_u <= shd_mins(7 downto 4); |
rtc.mins_u <= shd_mins(7 downto 4); |
elsif( rtc.mins_u > x"5")then |
rtc.mins_u <= (others => '0'); |
rtc.mins_u_ro <= '1'; |
rtc.mins_u <= (others => '0'); |
rtc.mins_u_ro <= '1'; |
end if; |
|
-- Hour counter (lower) |
rtc.hours_l <= rtc.hours_l + rtc.mins_u_ro; |
rtc.hours_l_ro <= '0'; |
rtc.hours_l <= rtc.hours_l + rtc.mins_u_ro; |
rtc.hours_l_ro <= '0'; |
if( update_rtc = '1' )then |
rtc.hours_l <= shd_hours(3 downto 0); |
rtc.hours_l <= shd_hours(3 downto 0); |
elsif( rtc.hours_l > x"9")then |
rtc.hours_l <= (others => '0'); |
rtc.hours_l_ro <= '1'; |
rtc.hours_l <= (others => '0'); |
rtc.hours_l_ro <= '1'; |
end if; |
|
-- Hour counter (upper) |
rtc.hours_u <= rtc.hours_u + rtc.hours_l_ro; |
rtc.hours_u <= rtc.hours_u + rtc.hours_l_ro; |
if( update_rtc = '1' )then |
rtc.hours_u <= shd_hours(7 downto 4); |
rtc.hours_u <= shd_hours(7 downto 4); |
end if; |
|
rtc.hours_u_ro <= '0'; |
rtc.hours_u_ro <= '0'; |
if( rtc.hours_u >= x"2" and rtc.hours_l > x"3" )then |
rtc.hours_l <= (others => '0'); |
rtc.hours_u <= (others => '0'); |
rtc.hours_u_ro <= '1'; |
rtc.hours_l <= (others => '0'); |
rtc.hours_u <= (others => '0'); |
rtc.hours_u_ro <= '1'; |
end if; |
|
-- Day of Week counter |
rtc.dow <= rtc.dow + rtc.hours_u_ro; |
rtc.dow <= rtc.dow + rtc.hours_u_ro; |
if( update_rtc = '1' )then |
rtc.dow <= shd_dow(2 downto 0); |
rtc.dow <= shd_dow(2 downto 0); |
elsif( rtc.dow = x"07")then |
rtc.dow <= (others => '0'); |
rtc.dow <= (others => '0'); |
end if; |
|
-- Copy the RTC registers to the shadow registers when the coherency |
-- timer is zero (RTC registers are static) |
if( update_shd = '1' and or_reduce(update_ctmr) = '0' )then |
shd_tens <= rtc.tens_u & rtc.tens_l; |
shd_secs <= rtc.secs_u & rtc.secs_l; |
shd_mins <= rtc.mins_u & rtc.mins_l; |
shd_hours <= rtc.hours_u & rtc.hours_l; |
shd_dow <= "00000" & rtc.dow; |
update_shd <= '0'; |
shd_tens <= rtc.tens_u & rtc.tens_l; |
shd_secs <= rtc.secs_u & rtc.secs_l; |
shd_mins <= rtc.mins_u & rtc.mins_l; |
shd_hours <= rtc.hours_u & rtc.hours_l; |
shd_dow <= "00000" & rtc.dow; |
update_shd <= '0'; |
end if; |
|
update_interval <= '0'; |
mask_pit_int <= '0'; |
|
Reg_Addr_q <= Reg_Addr; |
Wr_Data_q <= Wr_Data; |
Reg_Addr_q <= Reg_Addr; |
Wr_Data_q <= Wr_Data; |
|
Wr_En <= Addr_Match and Wr_Enable; |
update_rtc <= '0'; |
Wr_En <= Addr_Match and Wr_Enable; |
update_rtc <= '0'; |
if( Wr_En = '1' )then |
case( Reg_Addr_q )is |
when "000" => |
new_interval <= Wr_Data_q; |
update_interval <= '1'; |
interval <= Wr_Data_q; |
mask_pit_int <= '1'; |
|
when "001" => |
shd_tens <= Wr_Data_q; |
shd_tens <= Wr_Data_q; |
|
when "010" => |
shd_secs <= Wr_Data_q; |
shd_secs <= Wr_Data_q; |
|
when "011" => |
shd_mins <= Wr_Data_q; |
shd_mins <= Wr_Data_q; |
|
when "100" => |
shd_hours <= Wr_Data_q; |
shd_hours <= Wr_Data_q; |
|
when "101" => |
shd_dow <= Wr_Data_q; |
shd_dow <= Wr_Data_q; |
|
when "110" => |
update_rtc <= '1'; |
update_rtc <= '1'; |
|
when "111" => |
update_shd <= '1'; |
389,31 → 386,31
-- Coherency timer - ensures that the shadow registers are updated with |
-- valid time data by delaying updates until the rtc registers have |
-- finished cascading. |
update_ctmr <= update_ctmr - or_reduce(update_ctmr); |
update_ctmr <= update_ctmr - or_reduce(update_ctmr); |
if( rtc.frac_ro = '1' )then |
update_ctmr <= (others => '1'); |
update_ctmr <= (others => '1'); |
end if; |
|
Rd_Data <= OPEN8_NULLBUS; |
Rd_En <= Addr_Match and Rd_Enable; |
Rd_Data <= OPEN8_NULLBUS; |
Rd_En <= Addr_Match and Rd_Enable; |
if( Rd_En = '1' )then |
case( Reg_Addr_q )is |
when "000" => |
Rd_Data <= interval; |
Rd_Data <= interval; |
when "001" => |
Rd_Data <= shd_tens; |
Rd_Data <= shd_tens; |
when "010" => |
Rd_Data <= shd_secs; |
Rd_Data <= shd_secs; |
when "011" => |
Rd_Data <= shd_mins; |
Rd_Data <= shd_mins; |
when "100" => |
Rd_Data <= shd_hours; |
Rd_Data <= shd_hours; |
when "101" => |
Rd_Data <= shd_dow; |
Rd_Data <= shd_dow; |
when "110" => |
null; |
when "111" => |
Rd_Data <= update_shd & "0000000"; |
Rd_Data <= update_shd & "0000000"; |
when others => null; |
end case; |
end if; |
/o8_sys_timer.vhd
35,8 → 35,6
------------------ -------- --------------------------------------------------- |
-- Seth Henry 07/28/11 Design Start |
-- Seth Henry 12/19/19 Renamed Tmr_Out to Interrupt |
-- Seth Henry 04/09/20 Modified timer update logic to reset the timer on |
-- interval write. |
|
library ieee; |
use ieee.std_logic_1164.all; |
49,75 → 47,69
|
entity o8_sys_timer is |
generic( |
Sys_Freq : real; |
Reset_Level : std_logic; |
Address : ADDRESS_TYPE |
Sys_Freq : real; |
Reset_Level : std_logic; |
Address : ADDRESS_TYPE |
); |
port( |
Clock : in std_logic; |
Reset : in std_logic; |
uSec_Tick : out std_logic; |
Clock : in std_logic; |
Reset : in std_logic; |
uSec_Tick : out std_logic; |
-- |
Bus_Address : in ADDRESS_TYPE; |
Wr_Enable : in std_logic; |
Wr_Data : in DATA_TYPE; |
Rd_Enable : in std_logic; |
Rd_Data : out DATA_TYPE; |
Interrupt : out std_logic |
Bus_Address : in ADDRESS_TYPE; |
Wr_Enable : in std_logic; |
Wr_Data : in DATA_TYPE; |
Rd_Enable : in std_logic; |
Rd_Data : out DATA_TYPE; |
Interrupt : out std_logic |
); |
end entity; |
|
architecture behave of o8_sys_timer is |
|
constant User_Addr : ADDRESS_TYPE := Address; |
alias Comp_Addr is Bus_Address(15 downto 0); |
signal Addr_Match : std_logic := '0'; |
signal Wr_En : std_logic := '0'; |
signal Wr_Data_q : DATA_TYPE := OPEN8_NULLBUS; |
signal Rd_En : std_logic := '0'; |
signal Rd_En_q : std_logic := '0'; |
constant User_Addr : ADDRESS_TYPE := Address; |
alias Comp_Addr is Bus_Address(15 downto 0); |
signal Addr_Match : std_logic := '0'; |
signal Wr_En : std_logic := '0'; |
signal Wr_Data_q : DATA_TYPE := OPEN8_NULLBUS; |
signal Rd_En : std_logic := '0'; |
signal Rd_En_q : std_logic := '0'; |
|
signal Interval : DATA_TYPE := x"00"; |
signal Update_Interval : std_logic; |
signal New_Interval : DATA_TYPE := x"00"; |
signal Timer_Cnt : DATA_TYPE := x"00"; |
signal Interval : DATA_TYPE := x"00"; |
signal Timer_Cnt : DATA_TYPE := x"00"; |
|
constant DLY_1USEC_VAL : integer := integer(Sys_Freq / 1000000.0); |
constant DLY_1USEC_WDT : integer := ceil_log2(DLY_1USEC_VAL - 1); |
constant DLY_1USEC : std_logic_vector := |
constant DLY_1USEC_VAL: integer := integer(Sys_Freq / 1000000.0); |
constant DLY_1USEC_WDT: integer := ceil_log2(DLY_1USEC_VAL - 1); |
constant DLY_1USEC : std_logic_vector := |
conv_std_logic_vector(DLY_1USEC_VAL - 1, DLY_1USEC_WDT); |
|
signal uSec_Cntr : std_logic_vector( DLY_1USEC_WDT - 1 downto 0 ) |
:= (others => '0'); |
signal uSec_Tick_i : std_logic := '0'; |
signal uSec_Cntr : std_logic_vector( DLY_1USEC_WDT - 1 downto 0 ) |
:= (others => '0'); |
signal uSec_Tick_i : std_logic := '0'; |
begin |
|
uSec_Tick <= uSec_Tick_i; |
Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; |
uSec_Tick <= uSec_Tick_i; |
Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; |
|
io_reg: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
Wr_En <= '0'; |
Wr_Data_q <= x"00"; |
Rd_En <= '0'; |
Rd_Data <= OPEN8_NULLBUS; |
Interval <= x"00"; |
Update_Interval <= '0'; |
New_Interval <= x"00"; |
Wr_En <= '0'; |
Wr_Data_q <= x"00"; |
Rd_En <= '0'; |
Rd_Data <= OPEN8_NULLBUS; |
Interval <= x"00"; |
elsif( rising_edge( Clock ) )then |
Wr_En <= Addr_Match and Wr_Enable; |
Wr_Data_q <= Wr_Data; |
Update_Interval <= '0'; |
Wr_En <= Addr_Match and Wr_Enable; |
Wr_Data_q <= Wr_Data; |
if( Wr_En = '1' )then |
New_Interval <= Wr_Data_q; |
Update_Interval <= '1'; |
Interval <= Wr_Data_q; |
end if; |
|
Rd_Data <= (others => '0'); |
Rd_En <= Addr_Match and Rd_Enable; |
Rd_Data <= (others => '0'); |
Rd_En <= Addr_Match and Rd_Enable; |
if( Rd_En = '1' )then |
Rd_Data <= Interval; |
Rd_Data <= Interval; |
end if; |
end if; |
end process; |
125,14 → 117,14
uSec_Tick_i_proc: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
uSec_Cntr <= (others => '0'); |
uSec_Tick_i <= '0'; |
uSec_Cntr <= (others => '0'); |
uSec_Tick_i <= '0'; |
elsif( rising_edge( Clock ) )then |
uSec_Cntr <= uSec_Cntr - 1; |
uSec_Tick_i <= '0'; |
uSec_Cntr <= uSec_Cntr - 1; |
uSec_Tick_i <= '0'; |
if( uSec_Cntr = 0 )then |
uSec_Cntr <= DLY_1USEC; |
uSec_Tick_i <= '1'; |
uSec_Cntr <= DLY_1USEC; |
uSec_Tick_i <= '1'; |
end if; |
end if; |
end process; |
140,14 → 132,14
Interval_proc: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
Timer_Cnt <= x"00"; |
Interrupt <= '0'; |
Timer_Cnt <= x"00"; |
Interrupt <= '0'; |
elsif( rising_edge(Clock) )then |
Interrupt <= '0'; |
Timer_Cnt <= Timer_Cnt - uSec_Tick_i; |
Interrupt <= '0'; |
Timer_Cnt <= Timer_Cnt - uSec_Tick_i; |
if( or_reduce(Timer_Cnt) = '0' )then |
Timer_Cnt <= Interval; |
Interrupt <= or_reduce(Interval); -- Only trigger on Int > 0 |
Timer_Cnt <= Interval; |
Interrupt <= or_reduce(Interval); -- Only trigger on Int > 0 |
end if; |
end if; |
end process; |
/Open8_pkg.vhd
37,8 → 37,6
-- GP flags. |
-- Seth Henry 03/18/20 Added the ceil_log2 function, since it is used in |
-- memory sizing calculations. |
-- Seth Henry 04/09/20 Added the I bit to the exported flags for use in |
-- memory protection schemes. |
|
library ieee; |
use ieee.std_logic_1164.all; |
65,13 → 63,12
-- Note: INTERRUPT_BUNDLE must be exactly the same width as DATA_TYPE |
subtype INTERRUPT_BUNDLE is DATA_TYPE; |
|
subtype EXT_GP_FLAGS is std_logic_vector(4 downto 0); |
subtype EXT_GP_FLAGS is std_logic_vector(3 downto 0); |
|
constant EXT_ISR : integer := 0; |
constant EXT_GP4 : integer := 1; |
constant EXT_GP5 : integer := 2; |
constant EXT_GP6 : integer := 3; |
constant EXT_GP7 : integer := 4; |
constant EXT_GP4 : integer := 0; |
constant EXT_GP5 : integer := 1; |
constant EXT_GP6 : integer := 2; |
constant EXT_GP7 : integer := 3; |
|
constant OPEN8_NULLBUS : DATA_TYPE := x"00"; |
|