now gets accepted by Modelsim

This commit is contained in:
Markus Fröschle
2014-09-01 14:24:55 +00:00
parent 029388c6c4
commit 3b0e69127f
7 changed files with 296 additions and 277 deletions

View File

@@ -51,22 +51,22 @@
-- --
-- Revision 2006A 2006/06/03 WF -- Revision 2006A 2006/06/03 WF
-- Initial Release. -- Initial Release.
-- Revision 2K6B 2006/11/05 WF -- Revision 2K6B 2006/11/05 WF
-- Modified Source to compile with the Xilinx ISE. -- Modified Source to compile with the Xilinx ISE.
-- Fixed the polarity of the precompensation flag. -- Fixed the polarity of the precompensation flag.
-- The flag is no active '0'. Thanks to Jorma -- The flag is no active '0'. Thanks to Jorma
-- Oksanen for the information. -- Oksanen for the information.
-- Revision 2K8A 2008/02/26 WF -- Revision 2K8A 2008/02/26 WF
-- Fixed a bug in the 6ms delay. Thanks to Lyndon Amsdon. -- Fixed a bug in the 6ms delay. Thanks to Lyndon Amsdon.
-- Revision 2K8B 2008/12/24 WF -- Revision 2K8B 2008/12/24 WF
-- Bugfixes to avoid hanging state machine. -- Bugfixes to avoid hanging state machine.
-- Changed DELAY_30MS to DELAY_15MS, which is the correct value. Thanks to L. Amsdon for the information. -- Changed DELAY_30MS to DELAY_15MS, which is the correct value. Thanks to L. Amsdon for the information.
-- Removed CRC_BUSY. -- Removed CRC_BUSY.
-- Fixed a bug in the Delay for the state T2_VERIFY_AM. -- Fixed a bug in the Delay for the state T2_VERIFY_AM.
-- Revision 2K9A 2009/06/20 WF -- Revision 2K9A 2009/06/20 WF
-- Fix to provide correct LOST_DATA_TR00 flag during seek command. -- Fix to provide correct LOST_DATA_TR00 flag during seek command.
-- Revision 2K9A 2009/06/20 WF -- Revision 2K9A 2009/06/20 WF
-- Fixed the timing for DR_LOAD. -- Fixed the timing for DR_LOAD.
-- --
library ieee; library ieee;
@@ -74,7 +74,7 @@ use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
entity WF1772IP_CONTROL is entity WF1772IP_CONTROL is
port( port(
-- System control: -- System control:
CLK : in std_logic; CLK : in std_logic;
RESETn : in std_logic; RESETn : in std_logic;
@@ -83,7 +83,7 @@ entity WF1772IP_CONTROL is
A1, A0 : in std_logic; A1, A0 : in std_logic;
RWn : in std_logic; RWn : in std_logic;
CSn : in std_logic; CSn : in std_logic;
DDEn : in std_logic; DDEn : in std_logic;
-- Registers: -- Registers:
DR : in std_logic_vector(7 downto 0); -- Data register. DR : in std_logic_vector(7 downto 0); -- Data register.
@@ -129,7 +129,7 @@ entity WF1772IP_CONTROL is
-- DATA register control: -- DATA register control:
DR_CLR : out std_logic; -- Clear. DR_CLR : out std_logic; -- Clear.
DR_LOAD : out std_logic; -- LOAD. DR_LOAD : out std_logic; -- LOAD.
-- Shift register control: -- Shift register control:
SHFT_LOAD_ND : out std_logic; -- Load normal data. SHFT_LOAD_ND : out std_logic; -- Load normal data.
SHFT_LOAD_SD : out std_logic; -- Load special data. SHFT_LOAD_SD : out std_logic; -- Load special data.
@@ -175,7 +175,7 @@ architecture BEHAVIOR of WF1772IP_CONTROL is
signal DATA_RD : boolean; signal DATA_RD : boolean;
signal CMD_WR : boolean; signal CMD_WR : boolean;
signal STAT_RD : boolean; signal STAT_RD : boolean;
signal DELAY : boolean; signal DELAY : boolean;
signal DRQ_I : std_logic; signal DRQ_I : std_logic;
signal INDEX_CNT : boolean; signal INDEX_CNT : boolean;
signal DIR : std_logic; signal DIR : std_logic;
@@ -186,12 +186,12 @@ architecture BEHAVIOR of WF1772IP_CONTROL is
signal SECT_LEN : unsigned (10 downto 0); signal SECT_LEN : unsigned (10 downto 0);
signal TRACKMEM : std_logic_vector(7 downto 0); signal TRACKMEM : std_logic_vector(7 downto 0);
signal T3_TRADR : boolean; signal T3_TRADR : boolean;
signal T3_DATATYPE : std_logic_vector(7 downto 0); signal T3_DATATYPE : std_logic_vector(7 downto 0);
begin begin
-- The Forced interrupt stops any command at the end of an internal micro instruction. -- The Forced interrupt stops any command at the end of an internal micro instruction.
-- Forced interrupt waits until ALU operations in progress are complete (CRC calculations, -- Forced interrupt waits until ALU operations in progress are complete (CRC calculations,
-- compares etc.). the TYPE_IV_BREAK controls this behavior. -- compares etc.). the TYPE_IV_BREAK controls this behavior.
TYPE_IV_BREAK <= true when CMD(7 downto 4) = x"D" and DELAY = true else false; TYPE_IV_BREAK <= true when CMD(7 downto 4) = x"D" and DELAY = true else false;
CMD_REG: process(RESETn, CLK) CMD_REG: process(RESETn, CLK)
begin begin
@@ -255,7 +255,7 @@ begin
when DECODE => when DECODE =>
case CMD(7 downto 5) is case CMD(7 downto 5) is
when "000" => -- 'restore', 'seek'. when "000" => -- 'restore', 'seek'.
NEXT_CMD_STATE <= T1_SEEK_RESTORE; NEXT_CMD_STATE <= T1_SEEK_RESTORE;
when "001" |"010" | "011" => -- 'step', 'step in', 'step out'. when "001" |"010" | "011" => -- 'step', 'step in', 'step out'.
NEXT_CMD_STATE <= T1_STEPPING; NEXT_CMD_STATE <= T1_STEPPING;
when "100" | "101" => -- 'read sector', 'write sector' when "100" | "101" => -- 'read sector', 'write sector'
@@ -271,9 +271,9 @@ begin
when '1' => NEXT_CMD_STATE <= T3_WR; when '1' => NEXT_CMD_STATE <= T3_WR;
when others => NEXT_CMD_STATE <= T3_WR; -- Dummy for U, X, Z, W, H, L, -. when others => NEXT_CMD_STATE <= T3_WR; -- Dummy for U, X, Z, W, H, L, -.
end case; end case;
when others => when others =>
-- The following NEXT_CMD_STATE is chosen to compile fine with -- The following NEXT_CMD_STATE is chosen to compile fine with
-- the Xilinx ISE not to produce a latch. -- the Xilinx ISE not to produce a latch.
NEXT_CMD_STATE <= IDLE; -- Never true due to IDLE preselection. NEXT_CMD_STATE <= IDLE; -- Never true due to IDLE preselection.
end case; end case;
-------------------------------------------------------------------- --------------------------------------------------------------------
@@ -283,7 +283,7 @@ begin
-- In this state, the data register and the track register are updated, if the -- In this state, the data register and the track register are updated, if the
-- command is a RESTORE. The update is done further down with the track register -- command is a RESTORE. The update is done further down with the track register
-- and the data register controls. -- and the data register controls.
NEXT_CMD_STATE <= T1_LOAD_SHFT; NEXT_CMD_STATE <= T1_LOAD_SHFT;
when T1_STEPPING => when T1_STEPPING =>
if CMD(4) = '1' then -- '1' means update track register. if CMD(4) = '1' then -- '1' means update track register.
NEXT_CMD_STATE <= T1_CHECK_DIR; NEXT_CMD_STATE <= T1_CHECK_DIR;
@@ -315,7 +315,7 @@ begin
else else
NEXT_CMD_STATE <= T1_STEP; NEXT_CMD_STATE <= T1_STEP;
end if; end if;
when T1_STEP => when T1_STEP =>
NEXT_CMD_STATE <= T1_TRAP; NEXT_CMD_STATE <= T1_TRAP;
when T1_TRAP => when T1_TRAP =>
if STEP_TRAP = true then if STEP_TRAP = true then
@@ -373,16 +373,16 @@ begin
else else
NEXT_CMD_STATE <= T1_SCAN_CRC; NEXT_CMD_STATE <= T1_SCAN_CRC;
end if; end if;
when T1_VERIFY_CRC => when T1_VERIFY_CRC =>
-- The CRC logic starts during T1_SPINDOWN (missing clock transitions). -- The CRC logic starts during T1_SPINDOWN (missing clock transitions).
if DELAY = true then if DELAY = true then
if CRC_ERR = '1' then if CRC_ERR = '1' then
NEXT_CMD_STATE <= T1_SPINDOWN; -- CRC error. NEXT_CMD_STATE <= T1_SPINDOWN; -- CRC error.
else else
NEXT_CMD_STATE <= IDLE; -- Operation finished. NEXT_CMD_STATE <= IDLE; -- Operation finished.
end if; end if;
else else
NEXT_CMD_STATE <= T1_VERIFY_CRC; -- Wait until CRC logic is ready. NEXT_CMD_STATE <= T1_VERIFY_CRC; -- Wait until CRC logic is ready.
end if; end if;
-------------------------------------------------------------------- --------------------------------------------------------------------
------------------ special type2 command stuff --------------------- ------------------ special type2 command stuff ---------------------
@@ -737,7 +737,7 @@ begin
DELCNT := DELCNT + 1; DELCNT := DELCNT + 1;
-- Bit count delays work on data strobes. -- Bit count delays work on data strobes.
-- Read from disk operation: -- Read from disk operation:
when T1_SCAN_TRACK | T1_SCAN_CRC | T1_VERIFY_CRC | T2_SCAN_TRACK | T2_SCAN_SECT | when T1_SCAN_TRACK | T1_SCAN_CRC | T1_VERIFY_CRC | T2_SCAN_TRACK | T2_SCAN_SECT |
T2_SCAN_LEN | T2_VERIFY_CRC_1 | T2_VERIFY_AM | T2_FIRSTBYTE | T2_SCAN_LEN | T2_VERIFY_CRC_1 | T2_VERIFY_AM | T2_FIRSTBYTE |
T2_NEXTBYTE | T2_VERIFY_CRC_2 | T3_SHIFT | T3_SHIFT_ADR | T3_VERIFY_CRC => T2_NEXTBYTE | T2_VERIFY_CRC_2 | T3_SHIFT | T3_SHIFT_ADR | T3_VERIFY_CRC =>
if DATA_STRB = '1' then if DATA_STRB = '1' then
@@ -760,7 +760,7 @@ begin
when DELAY_15MS | T1_VERIFY_DELAY => when DELAY_15MS | T1_VERIFY_DELAY =>
case DELCNT is case DELCNT is
--when x"75300" => DELAY <= true; -- 30ms --when x"75300" => DELAY <= true; -- 30ms
when x"3A980" => DELAY <= true; -- 15ms, thanks to L. Amsdon. when x"3A980" => DELAY <= true; -- 15ms, thanks to L. Amsdon.
when others => DELAY <= false; when others => DELAY <= false;
end case; end case;
when T1_CHECK_DIR => when T1_CHECK_DIR =>
@@ -782,7 +782,7 @@ begin
DELAY <= true; DELAY <= true;
else else
DELAY <= false; DELAY <= false;
end if; end if;
when T1_SCAN_TRACK | T2_SCAN_TRACK | T2_SCAN_LEN | T2_FIRSTBYTE | T2_NEXTBYTE | when T1_SCAN_TRACK | T2_SCAN_TRACK | T2_SCAN_LEN | T2_FIRSTBYTE | T2_NEXTBYTE |
T2_WR_BYTE | T2_DATALOST | T2_WR_FF | T3_DATALOST | T3_SHIFT_ADR => T2_WR_BYTE | T2_DATALOST | T2_WR_FF | T3_DATALOST | T3_SHIFT_ADR =>
case DELCNT is case DELCNT is
@@ -791,7 +791,7 @@ begin
end case; end case;
when T1_SCAN_CRC => when T1_SCAN_CRC =>
case DELCNT is case DELCNT is
when x"00018" => DELAY <= true; -- Scan for 3 bytes. when x"00018" => DELAY <= true; -- Scan for 3 bytes.
when others => DELAY <= false; when others => DELAY <= false;
end case; end case;
when T2_WR_AM => when T2_WR_AM =>
@@ -803,9 +803,9 @@ begin
DELAY <= false; DELAY <= false;
end if; end if;
when T2_VERIFY_AM => when T2_VERIFY_AM =>
if DDEn = '1' and DELCNT >= x"00148" then -- FM mode. if DDEn = '1' and DELCNT >= x"00148" then -- FM mode.
DELAY <= true; -- (11+6+1)+1 = 19 Byte Times, plus 10 Byte times uncertainty. DELAY <= true; -- (11+6+1)+1 = 19 Byte Times, plus 10 Byte times uncertainty.
elsif DDEn = '0' and DELCNT >= x"00188" then -- MFM mode. elsif DDEn = '0' and DELCNT >= x"00188" then -- MFM mode.
DELAY <= true; -- (22+12+3+1)+1 = 39 Byte Times, plus 10 Byte times uncertainty. DELAY <= true; -- (22+12+3+1)+1 = 39 Byte Times, plus 10 Byte times uncertainty.
else else
DELAY <= false; DELAY <= false;
@@ -846,7 +846,7 @@ begin
case DELCNT is case DELCNT is
when x"00008" => DELAY <= true; -- Scan for 2 bytes but wait only 1 byte. when x"00008" => DELAY <= true; -- Scan for 2 bytes but wait only 1 byte.
when others => DELAY <= false; when others => DELAY <= false;
end case; end case;
when T1_VERIFY_CRC | T2_SCAN_SECT | T2_VERIFY_CRC_1 | T2_DELAY_B2 | T2_WR_CRC | T3_VERIFY_CRC => when T1_VERIFY_CRC | T2_SCAN_SECT | T2_VERIFY_CRC_1 | T2_DELAY_B2 | T2_WR_CRC | T3_VERIFY_CRC =>
case DELCNT is case DELCNT is
when x"00010" => DELAY <= true; -- Scan for 2 bytes (e. g. side and sector in T2_SCAN_SECT). when x"00010" => DELAY <= true; -- Scan for 2 bytes (e. g. side and sector in T2_SCAN_SECT).
@@ -887,23 +887,23 @@ begin
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
case CMD_STATE is case CMD_STATE is
-- Be aware that there must sometimes checked several states for the presence of IPn! -- Be aware that there must sometimes checked several states for the presence of IPn!
when SPINUP | T1_SPINDOWN | T1_SCAN_TRACK | T1_SCAN_CRC | T1_VERIFY_CRC | when SPINUP | T1_SPINDOWN | T1_SCAN_TRACK | T1_SCAN_CRC | T1_VERIFY_CRC |
T2_INIT | T2_SCAN_TRACK | T2_SCAN_SECT |T2_SCAN_LEN | T2_VERIFY_CRC_1 | T3_RD_ADR | T3_VERIFY_AM => T2_INIT | T2_SCAN_TRACK | T2_SCAN_SECT |T2_SCAN_LEN | T2_VERIFY_CRC_1 | T3_RD_ADR | T3_VERIFY_AM =>
if IPn = '0' and LOCK = false then -- Count the index pulses. if IPn = '0' and LOCK = false then -- Count the index pulses.
CNT := CNT + 1; CNT := CNT + 1;
LOCK := true; LOCK := true;
elsif IPn = '1' then elsif IPn = '1' then
LOCK := false; LOCK := false;
end if; end if;
-- --
if TIMEOUT < x"17FFFFF" then -- Timeout of about 1.5s. if TIMEOUT < x"17FFFFF" then -- Timeout of about 1.5s.
TIMEOUT := TIMEOUT + 1; TIMEOUT := TIMEOUT + 1;
end if; end if;
when others => when others =>
CNT := x"0"; CNT := x"0";
TIMEOUT := (others => '0'); TIMEOUT := (others => '0');
end case; end case;
end if; end if;
-- --
if CMD_STATE = SPINUP and (CNT = "110" or TIMEOUT = x"17FFFFF") then -- 6 pulses or timeout. if CMD_STATE = SPINUP and (CNT = "110" or TIMEOUT = x"17FFFFF") then -- 6 pulses or timeout.
INDEX_CNT <= true; INDEX_CNT <= true;
@@ -1042,9 +1042,9 @@ begin
if (DATA_RD = true or DATA_WR = true) then if (DATA_RD = true or DATA_WR = true) then
DRQ_I <= '0'; DRQ_I <= '0';
end if; end if;
end if; end if;
-- --
DRQ <= DRQ_I; -- Copy to entity. DRQ <= DRQ_I; -- Copy to entity.
-- --
end process P_DRQ; end process P_DRQ;
@@ -1066,7 +1066,7 @@ begin
elsif CMD_STATE = IDLE then elsif CMD_STATE = IDLE then
BUSY <= '0'; -- Reset BUSY after entering IDLE in any case. BUSY <= '0'; -- Reset BUSY after entering IDLE in any case.
end if; end if;
end if; end if;
end process P_BUSY; end process P_BUSY;
P_SEEK_RNF: process(RESETn, CLK) P_SEEK_RNF: process(RESETn, CLK)
@@ -1094,7 +1094,7 @@ begin
if RESETn = '0' then if RESETn = '0' then
INTRQ <= '0'; INTRQ <= '0';
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
-- Interrupt reset conditions: -- Interrupt reset conditions:
if STAT_RD = true and CMD /= x"D8" then if STAT_RD = true and CMD /= x"D8" then
-- No clear during immediately forced interrupt. -- No clear during immediately forced interrupt.
INTRQ <= '0'; -- Clear the flag when status register is read. INTRQ <= '0'; -- Clear the flag when status register is read.
@@ -1191,7 +1191,7 @@ begin
elsif IPn = '1' then elsif IPn = '1' then
LOCK := false; LOCK := false;
end if; end if;
-- --
if CMD_STATE = INIT and CMD_WR = false then if CMD_STATE = INIT and CMD_WR = false then
MO <= '1'; -- Start the motor for all command types I ... III in this state. MO <= '1'; -- Start the motor for all command types I ... III in this state.
elsif INDEXCNT = x"0" then elsif INDEXCNT = x"0" then
@@ -1248,7 +1248,7 @@ begin
null; null;
end case; end case;
end if; end if;
end process WRITEGATE; end process WRITEGATE;
RESTORE_TRAP: process(RESETn, CLK) RESTORE_TRAP: process(RESETn, CLK)
-- This process is responsible to supervise the RESTORE command. -- This process is responsible to supervise the RESTORE command.
@@ -1267,7 +1267,7 @@ begin
elsif CMD_STATE = T1_STEP and STEP_CNT < x"FF" then elsif CMD_STATE = T1_STEP and STEP_CNT < x"FF" then
STEP_CNT := STEP_CNT + 1; STEP_CNT := STEP_CNT + 1;
end if; end if;
end if; end if;
-- --
case STEP_CNT is case STEP_CNT is
when x"FF" => STEP_TRAP <= true; when x"FF" => STEP_TRAP <= true;
@@ -1286,7 +1286,8 @@ begin
if CMD_STATE = T1_STEP then if CMD_STATE = T1_STEP then
case DDEn is case DDEn is
when '1' => CNT := x"80"; --Start counter for FM step pulse. when '1' => CNT := x"80"; --Start counter for FM step pulse.
when '0' => CNT := x"40"; --Start counter for MFM step pulse. when '0' => CNT := x"40"; --Start counter for MFM step pulse.
when others => CNT := x"80";
end case; end case;
elsif CNT > x"00" then elsif CNT > x"00" then
CNT := CNT - 1; -- Count 63 or 127 CLK cycles ... CNT := CNT - 1; -- Count 63 or 127 CLK cycles ...
@@ -1380,10 +1381,10 @@ begin
STAT_RD <= true when CSn = '0' and A1 = '0' and A0 = '0' and RWn = '1' else false; -- Status register read. STAT_RD <= true when CSn = '0' and A1 = '0' and A0 = '0' and RWn = '1' else false; -- Status register read.
DATA_WR <= true when CSn = '0' and A1 = '1' and A0 = '1' and RWn = '0' else false; -- Data register write. DATA_WR <= true when CSn = '0' and A1 = '1' and A0 = '1' and RWn = '0' else false; -- Data register write.
DATA_RD <= true when CSn = '0' and A1 = '1' and A0 = '1' and RWn = '1' else false; -- Data register read. DATA_RD <= true when CSn = '0' and A1 = '1' and A0 = '1' and RWn = '1' else false; -- Data register read.
-- Track register arithmetics controls: -- Track register arithmetics controls:
TR_PRES <= '1' when CMD_STATE = T1_SEEK_RESTORE and CMD(7 downto 4) = "0000" else '0'; -- Restore command. TR_PRES <= '1' when CMD_STATE = T1_SEEK_RESTORE and CMD(7 downto 4) = "0000" else '0'; -- Restore command.
TR_CLR <= '1' when CMD_STATE = T1_HEAD_CTRL and TRACK00n = '0' and DIR = '0' else '0'; TR_CLR <= '1' when CMD_STATE = T1_HEAD_CTRL and TRACK00n = '0' and DIR = '0' else '0';
TR_INC <= '1' when CMD_STATE = T1_CHECK_DIR and DELAY = true and DIR = '1' else '0'; TR_INC <= '1' when CMD_STATE = T1_CHECK_DIR and DELAY = true and DIR = '1' else '0';
TR_DEC <= '1' when CMD_STATE = T1_CHECK_DIR and DELAY = true and DIR = '0' else '0'; TR_DEC <= '1' when CMD_STATE = T1_CHECK_DIR and DELAY = true and DIR = '0' else '0';
@@ -1445,7 +1446,7 @@ begin
PRECOMP_EN <= '1' when CMD(7 downto 4) = x"A" and CMD(1) = '0' else -- Write single sector. PRECOMP_EN <= '1' when CMD(7 downto 4) = x"A" and CMD(1) = '0' else -- Write single sector.
'1' when CMD(7 downto 4) = x"B" and CMD(1) = '0' else -- Write multiple sector. '1' when CMD(7 downto 4) = x"B" and CMD(1) = '0' else -- Write multiple sector.
'1' when CMD(7 downto 4) = x"F" and CMD(1) = '0' else '0'; -- Write track. '1' when CMD(7 downto 4) = x"F" and CMD(1) = '0' else '0'; -- Write track.
-- Disk data flow direction: -- Disk data flow direction:
DISK_RWn <= -- Write sector command: DISK_RWn <= -- Write sector command:
'0' when CMD_STATE = T2_WR_LEADIN else '0' when CMD_STATE = T2_WR_LEADIN else

View File

@@ -15,15 +15,15 @@
---- To understand how the code works in detail refer to the free ---- ---- To understand how the code works in detail refer to the free ----
---- US patent no. 4,780,844. ---- ---- US patent no. 4,780,844. ----
---- ---- ---- ----
---- Attention: The settings for TOP and BOTTOM, which control ---- ---- Attention: The settings for TOP and BOTTOM, which control ----
---- the PLL frequency and for PHASE_CORR which control the PLL ---- ---- the PLL frequency and for PHASE_CORR which control the PLL ----
---- phase are rather critical for a good read condition! To test ---- ---- phase are rather critical for a good read condition! To test ----
---- the PLL in the WD1772 compatible core do the following: ---- ---- the PLL in the WD1772 compatible core do the following: ----
---- Sample on an oscilloscope on one channel the falling edge of ---- ---- Sample on an oscilloscope on one channel the falling edge of ----
---- the RDn pulse and on the other channel the PLL_DSTRB. The ---- ---- the RDn pulse and on the other channel the PLL_DSTRB. The ----
---- RDn must be located exactly between the PLL_DSTRB pulses. ---- ---- RDn must be located exactly between the PLL_DSTRB pulses. ----
---- Otherwise, the parameters TOP, BOTTOM and PHASE_CORR have to ---- ---- Otherwise, the parameters TOP, BOTTOM and PHASE_CORR have to ----
---- be optimized. ---- ---- be optimized. ----
---- ---- ---- ----
---- To Do: ---- ---- To Do: ----
---- - ---- ---- - ----
@@ -69,13 +69,13 @@
-- Revision 2K7B 2006/12/29 WF -- Revision 2K7B 2006/12/29 WF
-- Introduced several improvements based on a very good examination -- Introduced several improvements based on a very good examination
-- of the pll code by Jean Louis-Guerin. -- of the pll code by Jean Louis-Guerin.
-- Revision 2K8A 2008/07/14 WF -- Revision 2K8A 2008/07/14 WF
-- Minor changes. -- Minor changes.
-- Revision 2K8B 2008/12/24 WF -- Revision 2K8B 2008/12/24 WF
-- Improvement of the INPORT process. -- Improvement of the INPORT process.
-- Bugfix of the FREQ_AMOUNT counter: now stops if its value is zero. -- Bugfix of the FREQ_AMOUNT counter: now stops if its value is zero.
-- Several changes concerning the PLL parameters to improve the -- Several changes concerning the PLL parameters to improve the
-- stability of the PLL. -- stability of the PLL.
-- --
library ieee; library ieee;
@@ -86,21 +86,21 @@ entity WF1772IP_DIGITAL_PLL is
generic( generic(
-- The valid range of the period counter of the PLL is given by the TOP and BOTTOM -- The valid range of the period counter of the PLL is given by the TOP and BOTTOM
-- limits. The counter range is therefore BOTTOM <= counter value <= TOP. -- limits. The counter range is therefore BOTTOM <= counter value <= TOP.
-- The generic PHASE_CORR is responsible fo the center setting of PLL_DSTRB concerning -- The generic PHASE_CORR is responsible fo the center setting of PLL_DSTRB concerning
-- the RDn period. -- the RDn period.
-- The nominal frequency setting is 128. So it is recommended to use TOP and BOTTOM -- The nominal frequency setting is 128. So it is recommended to use TOP and BOTTOM
-- settings symmetrically around 128. If TOP = BOTTOM = 128, the frequency control -- settings symmetrically around 128. If TOP = BOTTOM = 128, the frequency control
-- is disabled. TOP + PHASE_CORR may not exceed a value of 255. BOTTOM - PHASE_CORR -- is disabled. TOP + PHASE_CORR may not exceed a value of 255. BOTTOM - PHASE_CORR
-- may not drop below zero. -- may not drop below zero.
TOP : integer range 0 to 255 := 152; -- +18.0% TOP : integer range 0 to 255 := 152; -- +18.0%
BOTTOM : integer range 0 to 255 := 104; -- -18.0% BOTTOM : integer range 0 to 255 := 104; -- -18.0%
PHASE_CORR : unsigned (7 downto 0) := to_unsigned(75, 8) PHASE_CORR : unsigned (7 downto 0) := to_unsigned(75, 8)
); );
port( port(
-- System control -- System control
CLK : in std_logic; -- 16MHz clock. CLK : in std_logic; -- 16MHz clock.
RESETn : in std_logic; RESETn : in std_logic;
-- Controls -- Controls
DDEn : in std_logic; -- Double density enable. DDEn : in std_logic; -- Double density enable.
HDTYPE : in std_logic; -- This control is '1' when HD disks are inserted. HDTYPE : in std_logic; -- This control is '1' when HD disks are inserted.
@@ -117,7 +117,7 @@ architecture BEHAVIOR of WF1772IP_DIGITAL_PLL is
signal RD_In : std_logic; signal RD_In : std_logic;
signal UP, DOWN : std_logic; signal UP, DOWN : std_logic;
signal PHASE_DECREASE : std_logic; signal PHASE_DECREASE : std_logic;
signal PHASE_INCREASE : std_logic; signal PHASE_INCREASE : std_logic;
signal HI_STOP, LOW_STOP : std_logic; signal HI_STOP, LOW_STOP : std_logic;
signal PER_CNT : unsigned (7 downto 0); signal PER_CNT : unsigned (7 downto 0);
signal ADDER_IN : unsigned (7 downto 0); signal ADDER_IN : unsigned (7 downto 0);
@@ -126,17 +126,17 @@ signal RD_PULSE : std_logic;
signal ROLL_OVER : std_logic; signal ROLL_OVER : std_logic;
signal HISTORY_REG : std_logic_vector(1 downto 0); signal HISTORY_REG : std_logic_vector(1 downto 0);
signal ERROR_HISTORY : integer range 0 to 2; signal ERROR_HISTORY : integer range 0 to 2;
begin begin
INPORT: process INPORT: process
-- This process is necessary due to the poor quality of the rising -- This process is necessary due to the poor quality of the rising
-- edge of RDn. Let it work on the negative clock edge. -- edge of RDn. Let it work on the negative clock edge.
begin begin
wait until CLK = '0' and CLK' event; wait until CLK = '0' and CLK' event;
RD_In <= RDn; RD_In <= RDn;
end process INPORT; end process INPORT;
EDGEDETECT: process(RESETn, CLK) EDGEDETECT: process(RESETn, CLK)
-- This process forms a falling edge detector for the incoming -- This process forms a falling edge detector for the incoming
-- data read port. The output (RD_PULSE) goes high for exactly -- data read port. The output (RD_PULSE) goes high for exactly
-- one clock period after the RDn is low and the positive -- one clock period after the RDn is low and the positive
-- clock edge is detected. -- clock edge is detected.
@@ -145,13 +145,13 @@ begin
if RESETn = '0' then if RESETn = '0' then
RD_PULSE <= '0'; RD_PULSE <= '0';
LOCK := false; LOCK := false;
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
if DISK_RWn = '0' then -- Disable detector in write mode. if DISK_RWn = '0' then -- Disable detector in write mode.
RD_PULSE <= '0'; RD_PULSE <= '0';
elsif RD_In = '0' and LOCK = false then elsif RD_In = '0' and LOCK = false then
RD_PULSE <= '1'; -- READ_PULSE is inverted against RDn RD_PULSE <= '1'; -- READ_PULSE is inverted against RDn
LOCK := true; LOCK := true;
elsif RD_In = '1' then elsif RD_In = '1' then
LOCK := false; LOCK := false;
RD_PULSE <= '0'; RD_PULSE <= '0';
else else
@@ -161,19 +161,19 @@ begin
end process EDGEDETECT; end process EDGEDETECT;
PERIOD_CNT: process(RESETn, CLK) PERIOD_CNT: process(RESETn, CLK)
-- This process provides the nominal variable added to the adder. To achieve a good -- This process provides the nominal variable added to the adder. To achieve a good
-- settling time of the PLL in all cases, the period counter is controlled via the DDEn -- settling time of the PLL in all cases, the period counter is controlled via the DDEn
-- and HDTYPE flags respective to its added value. Be aware, that in case of adding "10" -- and HDTYPE flags respective to its added value. Be aware, that in case of adding "10"
-- or "11", the TOP value may be exceeded or the period counter may drop below the BOTTOM -- or "11", the TOP value may be exceeded or the period counter may drop below the BOTTOM
-- value. The higher the value added, the faster will be the settling time of phase locked -- value. The higher the value added, the faster will be the settling time of phase locked
-- loop . -- loop .
begin begin
if RESETn = '0' then if RESETn = '0' then
PER_CNT <= "10000000"; -- Initial value is 128. PER_CNT <= "10000000"; -- Initial value is 128.
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
if UP = '1' then if UP = '1' then
PER_CNT <= PER_CNT + 1; PER_CNT <= PER_CNT + 1;
elsif DOWN = '1' then elsif DOWN = '1' then
PER_CNT <= PER_CNT - 1; PER_CNT <= PER_CNT - 1;
end if; end if;
end if; end if;
@@ -185,9 +185,9 @@ begin
ADDER_IN <= -- This DISK_RWn = '0' implementation keeps the last phase information ADDER_IN <= -- This DISK_RWn = '0' implementation keeps the last phase information
-- of the PLL in read from disk mode. It should be a good solution concer- -- of the PLL in read from disk mode. It should be a good solution concer-
-- ning alternative read write cycles. -- ning alternative read write cycles.
"10000000" when DISK_RWn = '0' else -- Nominal value for write to disk. "10000000" when DISK_RWn = '0' else -- Nominal value for write to disk.
(PER_CNT + PHASE_CORR) when PHASE_INCREASE = '1' else -- Phase lags. (PER_CNT + PHASE_CORR) when PHASE_INCREASE = '1' else -- Phase lags.
(PER_CNT - PHASE_CORR) when PHASE_DECREASE = '1' else -- Phase leeds. (PER_CNT - PHASE_CORR) when PHASE_DECREASE = '1' else -- Phase leeds.
(PER_CNT); -- No phase correction; (PER_CNT); -- No phase correction;
ADDER: process(RESETn, CLK, DDEn, HDTYPE) ADDER: process(RESETn, CLK, DDEn, HDTYPE)
@@ -207,7 +207,7 @@ begin
ADDER_DATA := (others => '0'); ADDER_DATA := (others => '0');
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
ADDER_DATA := ADDER_DATA + ADDER_IN; ADDER_DATA := ADDER_DATA + ADDER_IN;
end if; end if;
-- --
cat := DDEn & HDTYPE; cat := DDEn & HDTYPE;
case cat is case cat is
@@ -219,6 +219,7 @@ begin
ADDER_MSBs <= std_logic_vector(ADDER_DATA(11 downto 9)); ADDER_MSBs <= std_logic_vector(ADDER_DATA(11 downto 9));
when "10" => -- FM mode using DD disks, results in 4us inspection period: when "10" => -- FM mode using DD disks, results in 4us inspection period:
ADDER_MSBs <= std_logic_vector(ADDER_DATA(12 downto 10)); ADDER_MSBs <= std_logic_vector(ADDER_DATA(12 downto 10));
when others => ADDER_MSBs <= std_logic_vector(ADDER_DATA(11 downto 9));
end case; end case;
end process ADDER; end process ADDER;
@@ -303,7 +304,7 @@ begin
if RESETn = '0' then if RESETn = '0' then
FREQ_AMOUNT := "0000"; FREQ_AMOUNT := "0000";
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
if RD_PULSE = '1' then -- Load the frequency amount register. if RD_PULSE = '1' then -- Load the frequency amount register.
case ERROR_HISTORY is case ERROR_HISTORY is
when 2 => when 2 =>
case ADDER_MSBs is case ADDER_MSBs is
@@ -315,6 +316,7 @@ begin
when "101" => FREQ_AMOUNT := "1010"; when "101" => FREQ_AMOUNT := "1010";
when "110" => FREQ_AMOUNT := "1011"; when "110" => FREQ_AMOUNT := "1011";
when "111" => FREQ_AMOUNT := "1100"; when "111" => FREQ_AMOUNT := "1100";
when others => FREQ_AMOUNT := "0100";
end case; end case;
when 1 => when 1 =>
case ADDER_MSBs is case ADDER_MSBs is
@@ -326,14 +328,15 @@ begin
when "101" => FREQ_AMOUNT := "1001"; when "101" => FREQ_AMOUNT := "1001";
when "110" => FREQ_AMOUNT := "1010"; when "110" => FREQ_AMOUNT := "1010";
when "111" => FREQ_AMOUNT := "1011"; when "111" => FREQ_AMOUNT := "1011";
end case; when others => FREQ_AMOUNT := "0011";
end case;
when others => when others =>
FREQ_AMOUNT := "0000"; FREQ_AMOUNT := "0000";
end case; end case;
elsif FREQ_AMOUNT(2 downto 0) > "000" then elsif FREQ_AMOUNT(2 downto 0) > "000" then
FREQ_AMOUNT := FREQ_AMOUNT - 1; -- Modify the frequency amount register. FREQ_AMOUNT := FREQ_AMOUNT - 1; -- Modify the frequency amount register.
end if; end if;
end if; end if;
-- --
if FREQ_AMOUNT(3) = '0' and FREQ_AMOUNT(2 downto 0) /= "000" and HI_STOP = '0' then if FREQ_AMOUNT(3) = '0' and FREQ_AMOUNT(2 downto 0) /= "000" and HI_STOP = '0' then
-- FREQ_AMOUNT(3) = '0' means Frequency is too low. Count up when counter is not at HI_STOP. -- FREQ_AMOUNT(3) = '0' means Frequency is too low. Count up when counter is not at HI_STOP.
@@ -353,15 +356,15 @@ begin
-- The phase decoder depends on the value of ADDER_MSBs. If the phase leeds, the most significant std_logic -- The phase decoder depends on the value of ADDER_MSBs. If the phase leeds, the most significant std_logic
-- of PHASE_AMOUNT indicates with a '0', that the next rollover should appear earlier. In case of a -- of PHASE_AMOUNT indicates with a '0', that the next rollover should appear earlier. In case of a
-- phase lag, the next rollover should come later (indicated by a '1' of the most significant std_logic of -- phase lag, the next rollover should come later (indicated by a '1' of the most significant std_logic of
-- PHASE_AMOUNT). -- PHASE_AMOUNT).
-- This implementation gives the freedom to adjust the phase amount individually for every mode -- This implementation gives the freedom to adjust the phase amount individually for every mode
-- depending on DDEn and HDTYPE. -- depending on DDEn and HDTYPE.
variable PHASE_AMOUNT: unsigned (5 downto 0); variable PHASE_AMOUNT: unsigned (5 downto 0);
begin begin
if RESETn = '0' then if RESETn = '0' then
PHASE_AMOUNT := "000000"; PHASE_AMOUNT := "000000";
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
if RD_PULSE = '1' and DDEn = '1' and HDTYPE = '0' then -- FM mode, single density. if RD_PULSE = '1' and DDEn = '1' and HDTYPE = '0' then -- FM mode, single density.
case ADDER_MSBs is -- Multiplier: 4. case ADDER_MSBs is -- Multiplier: 4.
when "000" => PHASE_AMOUNT := "010000"; when "000" => PHASE_AMOUNT := "010000";
when "001" => PHASE_AMOUNT := "001101"; when "001" => PHASE_AMOUNT := "001101";
@@ -371,6 +374,7 @@ begin
when "101" => PHASE_AMOUNT := "101000"; when "101" => PHASE_AMOUNT := "101000";
when "110" => PHASE_AMOUNT := "101100"; when "110" => PHASE_AMOUNT := "101100";
when "111" => PHASE_AMOUNT := "110000"; when "111" => PHASE_AMOUNT := "110000";
when others => PHASE_AMOUNT := "010000";
end case; end case;
elsif RD_PULSE = '1' and DDEn = '1' and HDTYPE = '1' then -- FM mode, double density elsif RD_PULSE = '1' and DDEn = '1' and HDTYPE = '1' then -- FM mode, double density
case ADDER_MSBs is -- Multiplier: 2. case ADDER_MSBs is -- Multiplier: 2.
@@ -382,43 +386,46 @@ begin
when "101" => PHASE_AMOUNT := "100100"; when "101" => PHASE_AMOUNT := "100100";
when "110" => PHASE_AMOUNT := "100110"; when "110" => PHASE_AMOUNT := "100110";
when "111" => PHASE_AMOUNT := "101000"; when "111" => PHASE_AMOUNT := "101000";
when others => PHASE_AMOUNT := "001000";
end case; end case;
elsif RD_PULSE = '1' and DDEn = '0' and HDTYPE = '0' then -- MFM mode, single density elsif RD_PULSE = '1' and DDEn = '0' and HDTYPE = '0' then -- MFM mode, single density
case ADDER_MSBs is -- Multiplier: 2. case ADDER_MSBs is -- Multiplier: 2.
when "000" => PHASE_AMOUNT := "000110"; when "000" => PHASE_AMOUNT := "000110";
when "001" => PHASE_AMOUNT := "000100"; when "001" => PHASE_AMOUNT := "000100";
when "010" => PHASE_AMOUNT := "000011"; when "010" => PHASE_AMOUNT := "000011";
when "011" => PHASE_AMOUNT := "000010"; when "011" => PHASE_AMOUNT := "000010";
when "100" => PHASE_AMOUNT := "100010"; when "100" => PHASE_AMOUNT := "100010";
when "101" => PHASE_AMOUNT := "100011"; when "101" => PHASE_AMOUNT := "100011";
when "110" => PHASE_AMOUNT := "100100"; when "110" => PHASE_AMOUNT := "100100";
when "111" => PHASE_AMOUNT := "100110"; when "111" => PHASE_AMOUNT := "100110";
when others => PHASE_AMOUNT := "000110";
end case; end case;
elsif RD_PULSE = '1' and DDEn = '0' and HDTYPE = '1' then -- MFM mode, double density. elsif RD_PULSE = '1' and DDEn = '0' and HDTYPE = '1' then -- MFM mode, double density.
case ADDER_MSBs is -- Multiplier: 1. case ADDER_MSBs is -- Multiplier: 1.
when "000" => PHASE_AMOUNT := "000100"; when "000" => PHASE_AMOUNT := "000100";
when "001" => PHASE_AMOUNT := "000011"; when "001" => PHASE_AMOUNT := "000011";
when "010" => PHASE_AMOUNT := "000010"; when "010" => PHASE_AMOUNT := "000010";
when "011" => PHASE_AMOUNT := "000001"; when "011" => PHASE_AMOUNT := "000001";
when "100" => PHASE_AMOUNT := "100001"; when "100" => PHASE_AMOUNT := "100001";
when "101" => PHASE_AMOUNT := "100010"; when "101" => PHASE_AMOUNT := "100010";
when "110" => PHASE_AMOUNT := "100011"; when "110" => PHASE_AMOUNT := "100011";
when "111" => PHASE_AMOUNT := "100100"; when "111" => PHASE_AMOUNT := "100100";
when others => PHASE_AMOUNT := "000100";
end case; end case;
else -- Modify phase amount register: else -- Modify phase amount register:
if PHASE_AMOUNT(4 downto 0) > x"0" then if PHASE_AMOUNT(4 downto 0) > x"0" then
PHASE_AMOUNT := PHASE_AMOUNT - 1; PHASE_AMOUNT := PHASE_AMOUNT - 1;
end if; end if;
end if; end if;
end if; end if;
-- --
if PHASE_AMOUNT(5) = '0' and PHASE_AMOUNT(4 downto 0) > x"0" then if PHASE_AMOUNT(5) = '0' and PHASE_AMOUNT(4 downto 0) > x"0" then
-- PHASE_AMOUNT(5) = '0' means, that the phase leeds. -- PHASE_AMOUNT(5) = '0' means, that the phase leeds.
PHASE_INCREASE <= '1'; -- Speed phase up, accelerate next rollover. PHASE_INCREASE <= '1'; -- Speed phase up, accelerate next rollover.
PHASE_DECREASE <= '0'; PHASE_DECREASE <= '0';
elsif PHASE_AMOUNT(5) = '1' and PHASE_AMOUNT(4 downto 0) > x"0" then elsif PHASE_AMOUNT(5) = '1' and PHASE_AMOUNT(4 downto 0) > x"0" then
-- PHASE_AMOUNT(5) = '1' means, that the phase lags. -- PHASE_AMOUNT(5) = '1' means, that the phase lags.
PHASE_INCREASE <= '0'; PHASE_INCREASE <= '0';
PHASE_DECREASE <= '1'; -- Speed phase down, delay of next rollover. PHASE_DECREASE <= '1'; -- Speed phase down, delay of next rollover.
else else
PHASE_INCREASE <= '0'; PHASE_INCREASE <= '0';

View File

@@ -56,10 +56,10 @@
-- Initial Release. -- Initial Release.
-- Revision 2K6B 2006/11/05 WF -- Revision 2K6B 2006/11/05 WF
-- Modified Source to compile with the Xilinx ISE. -- Modified Source to compile with the Xilinx ISE.
-- Revision 2K8A 2008/07/14 WF -- Revision 2K8A 2008/07/14 WF
-- Minor changes. -- Minor changes.
-- Revision 2K9A 2009/06/20 WF -- Revision 2K9A 2009/06/20 WF
-- MFM_In and MASK_SHFT have now synchronous reset to meet preset requirement. -- MFM_In and MASK_SHFT have now synchronous reset to meet preset requirement.
-- --
@@ -175,11 +175,11 @@ begin
variable LOCK : boolean; variable LOCK : boolean;
begin begin
if CLK = '1' and CLK' event then if CLK = '1' and CLK' event then
if RESETn = '0' then if RESETn = '0' then
MASK_SHFT := (others => '1'); MASK_SHFT := (others => '1');
LOCK := false; LOCK := false;
-- Load the mask shift register just in time when the shift register is -- Load the mask shift register just in time when the shift register is
-- loaded with valid data from the data register. -- loaded with valid data from the data register.
elsif SHFT_LOAD_SD = '1' and DDEn = '1' then -- FM mode. elsif SHFT_LOAD_SD = '1' and DDEn = '1' then -- FM mode.
case DR is case DR is
when x"F8" | x"F9" | x"FA" | x"FB" | x"FE" => MASK_SHFT := x"C7FFFF"; when x"F8" | x"F9" | x"FA" | x"FB" | x"FE" => MASK_SHFT := x"C7FFFF";
@@ -253,6 +253,7 @@ begin
else else
FM_In <= '1'; FM_In <= '1';
end if; end if;
when OTHERS => FM_In <= '0';
end case; end case;
end if; end if;
end process FM_ENCODER; end process FM_ENCODER;
@@ -421,9 +422,9 @@ begin
MFM_WR_OUT: process MFM_WR_OUT: process
begin begin
wait until CLK = '1' and CLK' event; wait until CLK = '1' and CLK' event;
if RESETn = '0' then if RESETn = '0' then
MFM_In <= '1'; MFM_In <= '1';
else else
case HDTYPE is case HDTYPE is
when '1' => -- HD type. when '1' => -- HD type.
if PRECOMP = EARLY and WR_CNT > x"0" and WR_CNT <= x"9" then if PRECOMP = EARLY and WR_CNT > x"0" and WR_CNT <= x"9" then
@@ -445,6 +446,7 @@ begin
else else
MFM_In <= '1'; MFM_In <= '1';
end if; end if;
when others => MFM_In <= '0';
end case; end case;
end if; end if;
end process MFM_WR_OUT; end process MFM_WR_OUT;

View File

@@ -54,14 +54,14 @@
-- The timer is modified to work on the CLK instead -- The timer is modified to work on the CLK instead
-- of XTAL1. This modification is done to provide -- of XTAL1. This modification is done to provide
-- a synchronous design. -- a synchronous design.
-- Revision 2K8A 2008/02/29 WF -- Revision 2K8A 2008/02/29 WF
-- Fixed a serious prescaler bug. -- Fixed a serious prescaler bug.
-- Revision 2K9A 20090620 WF -- Revision 2K9A 20090620 WF
-- Introduced timer readback registers. -- Introduced timer readback registers.
-- TIMER_x_INT is now a strobe. -- TIMER_x_INT is now a strobe.
-- Minor improvements. -- Minor improvements.
-- Revision 2K11A 20110620 WF -- Revision 2K11A 20110620 WF
-- A minor change in the data readback logic (RWn is now taken into consideration). -- A minor change in the data readback logic (RWn is now taken into consideration).
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
@@ -102,7 +102,7 @@ entity WF68901IP_TIMERS is
); );
end entity WF68901IP_TIMERS; end entity WF68901IP_TIMERS;
architecture BEHAVIOR of WF68901IP_TIMERS is architecture BEHAVIOR of WF68901IP_TIMERS is
signal XTAL1_S : std_logic; signal XTAL1_S : std_logic;
signal XTAL_STRB : std_logic; signal XTAL_STRB : std_logic;
signal TACR : std_logic_vector(4 downto 0); -- Timer A control register. signal TACR : std_logic_vector(4 downto 0); -- Timer A control register.
@@ -115,11 +115,11 @@ signal TDDR : std_logic_vector(7 downto 0); -- Timer D data register.
signal TIMER_A : unsigned (7 downto 0); -- Timer A count register. signal TIMER_A : unsigned (7 downto 0); -- Timer A count register.
signal TIMER_B : unsigned (7 downto 0); -- Timer B count register. signal TIMER_B : unsigned (7 downto 0); -- Timer B count register.
signal TIMER_C : unsigned (7 downto 0); -- Timer C count register. signal TIMER_C : unsigned (7 downto 0); -- Timer C count register.
signal TIMER_D : unsigned (7 downto 0); -- Timer D count register. signal TIMER_D : unsigned (7 downto 0); -- Timer D count register.
signal TIMER_R_A : std_logic_vector (7 downto 0); -- Timer A readback register. signal TIMER_R_A : std_logic_vector (7 downto 0); -- Timer A readback register.
signal TIMER_R_B : std_logic_vector (7 downto 0); -- Timer B readback register. signal TIMER_R_B : std_logic_vector (7 downto 0); -- Timer B readback register.
signal TIMER_R_C : std_logic_vector (7 downto 0); -- Timer C readback register. signal TIMER_R_C : std_logic_vector (7 downto 0); -- Timer C readback register.
signal TIMER_R_D : std_logic_vector (7 downto 0); -- Timer D readback register. signal TIMER_R_D : std_logic_vector (7 downto 0); -- Timer D readback register.
signal A_CNTSTRB : std_logic; signal A_CNTSTRB : std_logic;
signal B_CNTSTRB : std_logic; signal B_CNTSTRB : std_logic;
signal C_CNTSTRB : std_logic; signal C_CNTSTRB : std_logic;
@@ -129,19 +129,19 @@ signal TBI_I : std_logic;
signal TAI_STRB : std_logic; -- Strobe for the event counter mode. signal TAI_STRB : std_logic; -- Strobe for the event counter mode.
signal TBI_STRB : std_logic; -- Strobe for the event counter mode. signal TBI_STRB : std_logic; -- Strobe for the event counter mode.
signal TAO_I : std_logic; -- Timer A output signal. signal TAO_I : std_logic; -- Timer A output signal.
signal TBO_I : std_logic; -- Timer A output signal. signal TBO_I : std_logic; -- Timer A output signal.
begin begin
SYNC: process SYNC: process
-- This process provides a 'clean' XTAL1. -- This process provides a 'clean' XTAL1.
-- Without this sync, the edge detector for -- Without this sync, the edge detector for
-- XTAL_STRB does not work properly. -- XTAL_STRB does not work properly.
begin begin
wait until CLK = '1' and CLK' event; wait until CLK = '1' and CLK' event;
XTAL1_S <= XTAL1; XTAL1_S <= XTAL1;
-- Polarity control for the event counter and the PWM mode: -- Polarity control for the event counter and the PWM mode:
TAI_I <= TAI xnor AER_4; TAI_I <= TAI xnor AER_4;
TBI_I <= TBI xnor AER_3; TBI_I <= TBI xnor AER_3;
end process SYNC; end process SYNC;
-- Output enables for timer A and timer B: -- Output enables for timer A and timer B:
-- The outputs are held low for asserted reset flags in the control registers TACR -- The outputs are held low for asserted reset flags in the control registers TACR
@@ -181,47 +181,47 @@ begin
end case; end case;
end if; end if;
end if; end if;
end process TIMER_REGISTERS; end process TIMER_REGISTERS;
TIMER_READBACK : process(RESETn, CLK) TIMER_READBACK : process(RESETn, CLK)
-- This process provides the readback information for the -- This process provides the readback information for the
-- timers A to D. The information read is the information -- timers A to D. The information read is the information
-- last clocked into the timer read register when the DSn -- last clocked into the timer read register when the DSn
-- pin had last gone high prior to the current read cycle. -- pin had last gone high prior to the current read cycle.
variable READ_A : boolean; variable READ_A : boolean;
variable READ_B : boolean; variable READ_B : boolean;
variable READ_C : boolean; variable READ_C : boolean;
variable READ_D : boolean; variable READ_D : boolean;
begin begin
if RESETn = '0' then if RESETn = '0' then
TIMER_R_A <= x"00"; TIMER_R_A <= x"00";
TIMER_R_B <= x"00"; TIMER_R_B <= x"00";
TIMER_R_C <= x"00"; TIMER_R_C <= x"00";
TIMER_R_D <= x"00"; TIMER_R_D <= x"00";
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
if DSn = '0' and RWn = '1' and RS = "01111" then if DSn = '0' and RWn = '1' and RS = "01111" then
READ_A := true; READ_A := true;
elsif DSn = '0' and RWn = '1' and RS = "10000" then elsif DSn = '0' and RWn = '1' and RS = "10000" then
READ_B := true; READ_B := true;
elsif DSn = '0' and RWn = '1' and RS = "10001" then elsif DSn = '0' and RWn = '1' and RS = "10001" then
READ_C := true; READ_C := true;
elsif DSn = '0' and RWn = '1' and RS = "10010" then elsif DSn = '0' and RWn = '1' and RS = "10010" then
READ_D := true; READ_D := true;
elsif DSn = '1' and READ_A = true then elsif DSn = '1' and READ_A = true then
TIMER_R_A <= std_logic_vector(TIMER_A); TIMER_R_A <= std_logic_vector(TIMER_A);
READ_A := false; READ_A := false;
elsif DSn = '1' and READ_B = true then elsif DSn = '1' and READ_B = true then
TIMER_R_B <= std_logic_vector(TIMER_B); TIMER_R_B <= std_logic_vector(TIMER_B);
READ_B := false; READ_B := false;
elsif DSn = '1' and READ_C = true then elsif DSn = '1' and READ_C = true then
TIMER_R_C <= std_logic_vector(TIMER_C); TIMER_R_C <= std_logic_vector(TIMER_C);
READ_C := false; READ_C := false;
elsif DSn = '1' and READ_D = true then elsif DSn = '1' and READ_D = true then
TIMER_R_D <= std_logic_vector(TIMER_D); TIMER_R_D <= std_logic_vector(TIMER_D);
READ_D := false; READ_D := false;
end if; end if;
end if; end if;
end process TIMER_READBACK; end process TIMER_READBACK;
DATA_OUT_EN <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS > "01011" and RS <= "10010" else '0'; DATA_OUT_EN <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS > "01011" and RS <= "10010" else '0';
DATA_OUT <= "000" & TACR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01100" else DATA_OUT <= "000" & TACR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01100" else
@@ -230,17 +230,17 @@ begin
TIMER_R_A when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01111" else TIMER_R_A when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01111" else
TIMER_R_B when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10000" else TIMER_R_B when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10000" else
TIMER_R_C when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10001" else TIMER_R_C when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10001" else
TIMER_R_D when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10010" else (others => '0'); TIMER_R_D when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10010" else (others => '0');
XTAL_STROBE: process(RESETn, CLK) XTAL_STROBE: process(RESETn, CLK)
-- This process provides a strobe with 1 clock cycle -- This process provides a strobe with 1 clock cycle
-- (CLK) length after every rising edge of XTAL1. -- (CLK) length after every rising edge of XTAL1.
variable LOCK : boolean; variable LOCK : boolean;
begin begin
if RESETn = '0' then if RESETn = '0' then
XTAL_STRB <= '0'; XTAL_STRB <= '0';
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
if XTAL1_S = '1' and LOCK = false then if XTAL1_S = '1' and LOCK = false then
XTAL_STRB <= '1'; XTAL_STRB <= '1';
LOCK := true; LOCK := true;
elsif XTAL1_S = '0' then elsif XTAL1_S = '0' then
@@ -293,7 +293,7 @@ begin
variable PRESCALE : unsigned (7 downto 0); variable PRESCALE : unsigned (7 downto 0);
begin begin
wait until CLK = '1' and CLK' event; wait until CLK = '1' and CLK' event;
A_CNTSTRB <= '0'; A_CNTSTRB <= '0';
if PRESCALE > x"00" and XTAL_STRB = '1' then if PRESCALE > x"00" and XTAL_STRB = '1' then
PRESCALE := PRESCALE - 1; PRESCALE := PRESCALE - 1;
elsif XTAL_STRB = '1' then elsif XTAL_STRB = '1' then
@@ -306,8 +306,9 @@ begin
when "010" => PRESCALE := x"09"; -- Prescaler = 10. when "010" => PRESCALE := x"09"; -- Prescaler = 10.
when "001" => PRESCALE := x"03"; -- Prescaler = 4. when "001" => PRESCALE := x"03"; -- Prescaler = 4.
when "000" => PRESCALE := x"00"; -- Timer stopped or event count mode. when "000" => PRESCALE := x"00"; -- Timer stopped or event count mode.
when others => PRESCALE := x"00";
end case; end case;
A_CNTSTRB <= '1'; A_CNTSTRB <= '1';
end if; end if;
end process PRESCALE_A; end process PRESCALE_A;
@@ -316,7 +317,7 @@ begin
variable PRESCALE : unsigned (7 downto 0); variable PRESCALE : unsigned (7 downto 0);
begin begin
wait until CLK = '1' and CLK' event; wait until CLK = '1' and CLK' event;
B_CNTSTRB <= '0'; B_CNTSTRB <= '0';
if PRESCALE > x"00" and XTAL_STRB = '1' then if PRESCALE > x"00" and XTAL_STRB = '1' then
PRESCALE := PRESCALE - 1; PRESCALE := PRESCALE - 1;
elsif XTAL_STRB = '1' then elsif XTAL_STRB = '1' then
@@ -329,40 +330,42 @@ begin
when "010" => PRESCALE := x"09"; -- Prescaler = 10. when "010" => PRESCALE := x"09"; -- Prescaler = 10.
when "001" => PRESCALE := x"03"; -- Prescaler = 4. when "001" => PRESCALE := x"03"; -- Prescaler = 4.
when "000" => PRESCALE := x"00"; -- Timer stopped or event count mode. when "000" => PRESCALE := x"00"; -- Timer stopped or event count mode.
when others => PRESCALE := x"00";
end case; end case;
B_CNTSTRB <= '1'; B_CNTSTRB <= '1';
end if; end if;
end process PRESCALE_B; end process PRESCALE_B;
PRESCALE_C: process PRESCALE_C: process
-- The prescalers work even if the RESETn is asserted. -- The prescalers work even if the RESETn is asserted.
variable PRESCALE : unsigned (7 downto 0); variable PRESCALE : unsigned (7 downto 0);
begin begin
wait until CLK = '1' and CLK' event; wait until CLK = '1' and CLK' event;
C_CNTSTRB <= '0'; C_CNTSTRB <= '0';
if PRESCALE > x"00" and XTAL_STRB = '1' then if PRESCALE > x"00" and XTAL_STRB = '1' then
PRESCALE := PRESCALE - 1; PRESCALE := PRESCALE - 1;
elsif XTAL_STRB = '1' then elsif XTAL_STRB = '1' then
case TCDCR(5 downto 3) is case TCDCR(5 downto 3) is
when "111" => PRESCALE := x"C7"; -- Prescaler = 200. when "111" => PRESCALE := x"C7"; -- Prescaler = 200.
when "110" => PRESCALE := x"63"; -- Prescaler = 100. when "110" => PRESCALE := x"63"; -- Prescaler = 100.
when "101" => PRESCALE := x"3F"; -- Prescaler = 64. when "101" => PRESCALE := x"3F"; -- Prescaler = 64.
when "100" => PRESCALE := x"31"; -- Prescaler = 50. when "100" => PRESCALE := x"31"; -- Prescaler = 50.
when "011" => PRESCALE := x"0F"; -- Prescaler = 16. when "011" => PRESCALE := x"0F"; -- Prescaler = 16.
when "010" => PRESCALE := x"09"; -- Prescaler = 10. when "010" => PRESCALE := x"09"; -- Prescaler = 10.
when "001" => PRESCALE := x"03"; -- Prescaler = 4. when "001" => PRESCALE := x"03"; -- Prescaler = 4.
when "000" => PRESCALE := x"00"; -- Timer stopped. when "000" => PRESCALE := x"00"; -- Timer stopped.
end case; when others => PRESCALE := x"00";
C_CNTSTRB <= '1'; end case;
end if; C_CNTSTRB <= '1';
end process PRESCALE_C; end if;
end process PRESCALE_C;
PRESCALE_D: process PRESCALE_D: process
-- The prescalers work even if the RESETn is asserted. -- The prescalers work even if the RESETn is asserted.
variable PRESCALE : unsigned (7 downto 0); variable PRESCALE : unsigned (7 downto 0);
begin begin
wait until CLK = '1' and CLK' event; wait until CLK = '1' and CLK' event;
D_CNTSTRB <= '0'; D_CNTSTRB <= '0';
if PRESCALE > x"00" and XTAL_STRB = '1' then if PRESCALE > x"00" and XTAL_STRB = '1' then
PRESCALE := PRESCALE - 1; PRESCALE := PRESCALE - 1;
elsif XTAL_STRB = '1' then elsif XTAL_STRB = '1' then
@@ -375,8 +378,9 @@ begin
when "010" => PRESCALE := x"09"; -- Prescaler = 10. when "010" => PRESCALE := x"09"; -- Prescaler = 10.
when "001" => PRESCALE := x"03"; -- Prescaler = 4. when "001" => PRESCALE := x"03"; -- Prescaler = 4.
when "000" => PRESCALE := x"00"; -- Timer stopped. when "000" => PRESCALE := x"00"; -- Timer stopped.
when others => PRESCALE := x"00";
end case; end case;
D_CNTSTRB <= '1'; D_CNTSTRB <= '1';
end if; end if;
end process PRESCALE_D; end process PRESCALE_D;
@@ -386,16 +390,16 @@ begin
-- Do not clear the timer registers during system reset. -- Do not clear the timer registers during system reset.
TAO_I <= '0'; TAO_I <= '0';
TIMER_A_INT <= '0'; TIMER_A_INT <= '0';
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
TIMER_A_INT <= '0'; TIMER_A_INT <= '0';
-- --
if CSn = '0' and DSn = '0' and RWn = '0' and RS = "01111" and TACR(3 downto 0) = x"0" then if CSn = '0' and DSn = '0' and RWn = '0' and RS = "01111" and TACR(3 downto 0) = x"0" then
-- The timer is reloaded simultaneously to it's timer data register, if it is off. -- The timer is reloaded simultaneously to it's timer data register, if it is off.
TIMER_A <= unsigned(DATA_IN); TIMER_A <= unsigned(DATA_IN);
else else
case TACR(3 downto 0) is case TACR(3 downto 0) is
when x"0" => -- Timer is off. when x"0" => -- Timer is off.
TAO_I <= '0'; TAO_I <= '0';
when x"1" | x"2" | x"3" | x"4" | x"5" | x"6" | x"7" => -- Delay counter mode. when x"1" | x"2" | x"3" | x"4" | x"5" | x"6" | x"7" => -- Delay counter mode.
if A_CNTSTRB = '1' and TIMER_A /= x"01" then -- Count. if A_CNTSTRB = '1' and TIMER_A /= x"01" then -- Count.
TIMER_A <= TIMER_A - 1; TIMER_A <= TIMER_A - 1;
@@ -420,6 +424,7 @@ begin
TAO_I <= not TAO_I; -- Toggle the timer A output pin. TAO_I <= not TAO_I; -- Toggle the timer A output pin.
TIMER_A_INT <= '1'; TIMER_A_INT <= '1';
end if; end if;
when others => TAO_I <= '0';
end case; end case;
end if; end if;
end if; end if;
@@ -431,16 +436,16 @@ begin
-- Do not clear the timer registers during system reset. -- Do not clear the timer registers during system reset.
TBO_I <= '0'; TBO_I <= '0';
TIMER_B_INT <= '0'; TIMER_B_INT <= '0';
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
TIMER_B_INT <= '0'; TIMER_B_INT <= '0';
-- --
if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10000" and TBCR(3 downto 0) = x"0" then if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10000" and TBCR(3 downto 0) = x"0" then
-- The timer is reloaded simultaneously to it's timer data register, if it is off. -- The timer is reloaded simultaneously to it's timer data register, if it is off.
TIMER_B <= unsigned(DATA_IN); TIMER_B <= unsigned(DATA_IN);
else else
case TBCR(3 downto 0) is case TBCR(3 downto 0) is
when x"0" => -- Timer is off. when x"0" => -- Timer is off.
TBO_I <= '0'; TBO_I <= '0';
when x"1" | x"2" | x"3" | x"4" | x"5" | x"6" | x"7" => -- Delay counter mode. when x"1" | x"2" | x"3" | x"4" | x"5" | x"6" | x"7" => -- Delay counter mode.
if B_CNTSTRB = '1' and TIMER_B /= x"01" then -- Count. if B_CNTSTRB = '1' and TIMER_B /= x"01" then -- Count.
TIMER_B <= TIMER_B - 1; TIMER_B <= TIMER_B - 1;
@@ -465,27 +470,28 @@ begin
TBO_I <= not TBO_I; -- Toggle the timer B output pin. TBO_I <= not TBO_I; -- Toggle the timer B output pin.
TIMER_B_INT <= '1'; TIMER_B_INT <= '1';
end if; end if;
when others => TBO_I <= '0';
end case; end case;
end if; end if;
end if; end if;
end process TIMERB; end process TIMERB;
TIMERC: process(RESETn, CLK) TIMERC: process(RESETn, CLK)
begin begin
if RESETn = '0' then if RESETn = '0' then
-- Do not clear the timer registers during system reset. -- Do not clear the timer registers during system reset.
TCO <= '0'; TCO <= '0';
TIMER_C_INT <= '0'; TIMER_C_INT <= '0';
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
TIMER_C_INT <= '0'; TIMER_C_INT <= '0';
-- --
if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10001" and TCDCR(5 downto 3) = "000" then if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10001" and TCDCR(5 downto 3) = "000" then
-- The timer is reloaded simultaneously to it's timer data register, if it is off. -- The timer is reloaded simultaneously to it's timer data register, if it is off.
TIMER_C <= unsigned(DATA_IN); TIMER_C <= unsigned(DATA_IN);
else else
case TCDCR(5 downto 3) is case TCDCR(5 downto 3) is
when "000" => -- Timer is off. when "000" => -- Timer is off.
TCO <= '0'; TCO <= '0';
when others => -- Delay counter mode. when others => -- Delay counter mode.
if C_CNTSTRB = '1' and TIMER_C /= x"01" then -- Count. if C_CNTSTRB = '1' and TIMER_C /= x"01" then -- Count.
TIMER_C <= TIMER_C - 1; TIMER_C <= TIMER_C - 1;
@@ -505,16 +511,16 @@ begin
-- Do not clear the timer registers during system reset. -- Do not clear the timer registers during system reset.
TDO <= '0'; TDO <= '0';
TIMER_D_INT <= '0'; TIMER_D_INT <= '0';
elsif CLK = '1' and CLK' event then elsif CLK = '1' and CLK' event then
TIMER_D_INT <= '0'; TIMER_D_INT <= '0';
-- --
if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10010" and TCDCR(2 downto 0) = "000" then if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10010" and TCDCR(2 downto 0) = "000" then
-- The timer is reloaded simultaneously to it's timer data register, if it is off. -- The timer is reloaded simultaneously to it's timer data register, if it is off.
TIMER_D <= unsigned(DATA_IN); TIMER_D <= unsigned(DATA_IN);
else else
case TCDCR(2 downto 0) is case TCDCR(2 downto 0) is
when "000" => -- Timer is off. when "000" => -- Timer is off.
TDO <= '0'; TDO <= '0';
when others => -- Delay counter mode. when others => -- Delay counter mode.
if D_CNTSTRB = '1' and TIMER_D /= x"01" then -- Count. if D_CNTSTRB = '1' and TIMER_D /= x"01" then -- Count.
TIMER_D <= TIMER_D - 1; TIMER_D <= TIMER_D - 1;

View File

@@ -50,8 +50,8 @@
-- Initial Release. -- Initial Release.
-- Revision 2K6B 2006/11/07 WF -- Revision 2K6B 2006/11/07 WF
-- Modified Source to compile with the Xilinx ISE. -- Modified Source to compile with the Xilinx ISE.
-- Revision 2K8A 2008/07/14 WF -- Revision 2K8A 2008/07/14 WF
-- Minor changes. -- Minor changes.
-- --
library ieee; library ieee;
@@ -184,6 +184,7 @@ begin
when "01" => LOOPBACK <= '0'; SD_LEVEL <= '0'; SDOUT_EN <= '1'; when "01" => LOOPBACK <= '0'; SD_LEVEL <= '0'; SDOUT_EN <= '1';
when "10" => LOOPBACK <= '0'; SD_LEVEL <= '1'; SDOUT_EN <= '1'; when "10" => LOOPBACK <= '0'; SD_LEVEL <= '1'; SDOUT_EN <= '1';
when "11" => LOOPBACK <= '1'; SD_LEVEL <= '1'; SDOUT_EN <= '1'; when "11" => LOOPBACK <= '1'; SD_LEVEL <= '1'; SDOUT_EN <= '1';
when others => LOOPBACK <= '0'; SD_LEVEL <= '0'; SDOUT_EN <= '0';
end case; end case;
end if; end if;
end process SOUT_CONFIG; end process SOUT_CONFIG;

View File

@@ -49,10 +49,10 @@
-- Initial Release. -- Initial Release.
-- Revision 2K6B 2006/11/07 WF -- Revision 2K6B 2006/11/07 WF
-- Modified Source to compile with the Xilinx ISE. -- Modified Source to compile with the Xilinx ISE.
-- Revision 2K8A 2008/07/14 WF -- Revision 2K8A 2008/07/14 WF
-- Minor changes. -- Minor changes.
-- Revision 2K9A 2009/06/20 WF -- Revision 2K9A 2009/06/20 WF
-- TDRE has now synchronous reset to meet preset requirement. -- TDRE has now synchronous reset to meet preset requirement.
-- --
library ieee; library ieee;
@@ -197,10 +197,11 @@ begin
elsif TR_STATE = LOAD_SHFT then elsif TR_STATE = LOAD_SHFT then
-- Load 'normal' data if there is no break condition: -- Load 'normal' data if there is no break condition:
case CL is case CL is
when "11" => SHIFT_REG <= "000" & TX_DATA(4 downto 0); -- 5 datastd_logics. when "11" => SHIFT_REG <= "000" & TX_DATA(4 downto 0); -- 5 databits.
when "10" => SHIFT_REG <= "00" & TX_DATA(5 downto 0); -- 6 datastd_logics. when "10" => SHIFT_REG <= "00" & TX_DATA(5 downto 0); -- 6 databits
when "01" => SHIFT_REG <= '0' & TX_DATA(6 downto 0); -- 7 datastd_logics. when "01" => SHIFT_REG <= '0' & TX_DATA(6 downto 0); -- 7 databits
when "00" => SHIFT_REG <= TX_DATA; -- 8 datastd_logics. when "00" => SHIFT_REG <= TX_DATA; -- 8 databits
when others => SHIFT_REG <= x"00";
end case; end case;
elsif TR_STATE = SHIFTOUT and CLK_STRB = '1' then elsif TR_STATE = SHIFTOUT and CLK_STRB = '1' then
SHIFT_REG <= '0' & SHIFT_REG(7 downto 1); -- Shift right. SHIFT_REG <= '0' & SHIFT_REG(7 downto 1); -- Shift right.
@@ -223,8 +224,8 @@ begin
-- Transmit data register empty flag. -- Transmit data register empty flag.
begin begin
wait until CLK = '1' and CLK' event; wait until CLK = '1' and CLK' event;
if RESETn = '0' then if RESETn = '0' then
TDRE <= '1'; TDRE <= '1';
elsif TE = '0' then elsif TE = '0' then
TDRE <= '1'; TDRE <= '1';
elsif TR_STATE = START and BREAK = '0' then elsif TR_STATE = START and BREAK = '0' then

View File

@@ -72,8 +72,8 @@
-- Revision 2K6B 2006/11/07 WF -- Revision 2K6B 2006/11/07 WF
-- Modified Source to compile with the Xilinx ISE. -- Modified Source to compile with the Xilinx ISE.
-- Top level file provided for SOC (systems on programmable chips). -- Top level file provided for SOC (systems on programmable chips).
-- Revision 2K8A 2008/07/14 WF -- Revision 2K8A 2008/07/14 WF
-- Minor changes. -- Minor changes.
-- --
library ieee; library ieee;
@@ -149,7 +149,8 @@ begin
BUSCYCLE <= INACTIVE when "000" | "010" | "101", BUSCYCLE <= INACTIVE when "000" | "010" | "101",
ADDRESS when "001" | "100" | "111", ADDRESS when "001" | "100" | "111",
R_READ when "011", R_READ when "011",
R_WRITE when "110"; R_WRITE when "110",
INACTIVE when others;
ADDRESSLATCH: process(RESETn, SYS_CLK) ADDRESSLATCH: process(RESETn, SYS_CLK)
-- This process is responsible to store the desired register -- This process is responsible to store the desired register