Advertisement
iocoder

fdc.vhd

Jan 3rd, 2015
1,679
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 28.17 KB | None | 0 0
  1. --------------------------------------------------------------------------------
  2. --------------------------------------------------------------------------------
  3. ----------------------     FLOPPY DISK CONTROLLER    ---------------------------
  4. --------------------------------------------------------------------------------
  5. --------------------------------------------------------------------------------
  6. --                                                                            --
  7. -- Floppy Disk Controller in VHDL.                                            --
  8. -- Copyright (C) <2015>  <Mostafa Abd El-Aziz>                                --
  9. --                                                                            --
  10. -- This program is free software: you can redistribute it and/or modify       --
  11. -- it under the terms of the GNU General Public License as published by       --
  12. -- the Free Software Foundation, either version 3 of the License, or          --
  13. -- (at your option) any later version.                                        --
  14. --                                                                            --
  15. -- This program is distributed in the hope that it will be useful,            --
  16. -- but WITHOUT ANY WARRANTY; without even the implied warranty of             --
  17. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              --
  18. -- GNU General Public License for more details.                               --
  19. --                                                                            --
  20. -- You should have received a copy of the GNU General Public License          --
  21. -- along with this program.  If not, see <http://www.gnu.org/licenses/>.      --
  22. --                                                                            --
  23. -- Contact: iocoder@aol.com                                                   --
  24. --                                                                            --
  25. --------------------------------------------------------------------------------
  26.  
  27. library IEEE;
  28. use IEEE.STD_LOGIC_1164.ALL;
  29. use IEEE.STD_LOGIC_ARITH.ALL;
  30. use IEEE.STD_LOGIC_UNSIGNED.ALL;
  31.  
  32. entity fdc is
  33.     Port (
  34.         -- Clock signals
  35.         CLK_50MHz : in  STD_LOGIC;
  36.         CLK_1MHz  : in  STD_LOGIC;
  37.  
  38.         -- debug
  39.         LED       : out STD_LOGIC_VECTOR (7 downto 0);
  40.  
  41.         -- CPU Interface
  42.         CS        : in  STD_LOGIC;
  43.         RD        : in  STD_LOGIC;
  44.         WR        : in  STD_LOGIC;
  45.         A         : in  STD_LOGIC_VECTOR (2 downto 0);
  46.         Din       : in  STD_LOGIC_VECTOR (7 downto 0);
  47.         Dout      : out STD_LOGIC_VECTOR (7 downto 0);
  48.  
  49.         -- Floppy Drive Interface
  50.         DENSEL    : out std_logic := '1'; -- density select
  51.         RESERVED  : in  std_logic;        -- reserved
  52.         INDEX     : in  std_logic;        -- index hole
  53.         MOTEA     : out std_logic := '1'; -- enable motor A
  54.         DRVSB     : out std_logic := '1'; -- select drive B
  55.         DRVSA     : out std_logic := '1'; -- select drive A
  56.         MOTEB     : out std_logic := '1'; -- enable motor B
  57.         DIR       : out std_logic := '1'; -- stepper motor direction
  58.         STEP      : out std_logic := '1'; -- stepper motor pulse
  59.         WDATE     : out std_logic := '1'; -- write data
  60.         WGATE     : out std_logic := '1'; -- write gate
  61.         TRK00     : in  std_logic;        -- track 0
  62.         WPT       : in  std_logic;        -- write protect
  63.         RDATA     : in  std_logic;        -- read data
  64.         SIDE1     : out std_logic := '1'; -- head select
  65.         DSKCHG    : in  std_logic         -- disk change
  66.     );
  67. end fdc;
  68.  
  69. architecture Behavioral of fdc is
  70.  
  71. -- read buffer
  72. type   rbuf_t is array (0 to 511) of STD_LOGIC_VECTOR(7 downto 0);
  73. signal rbuf             : rbuf_t                        := (others => x"00");
  74. signal rbuf_ptr         : integer range 0 to 100000     := 0;
  75. signal rbuf_addr        : integer range 0 to 100000     := 0;
  76. signal rbuf_write       : STD_LOGIC                     := '0';
  77. signal rbuf_data        : STD_LOGIC_VECTOR (7 downto 0) := x"00";
  78.  
  79. -- counter for internal operations:
  80. signal counter          : integer range 0 to 200000000  := 0;
  81.  
  82. -- phase of execution
  83. signal phase            : integer range 0 to 50         := 0;
  84.  
  85. -- disk state:
  86. signal motor_on         : std_logic                     := '0';
  87.  
  88. -- command request sync (if cmd_front != cmd_back, then busy)
  89. signal cmd_front        : integer range 0 to 100000     := 0;
  90. signal cmd_back         : integer range 0 to 100000     := 0;
  91. signal cmd_err          : std_logic                     := '0';
  92.  
  93. -- read command sync
  94. signal read_front       : integer range 0 to 100000     := 0;
  95. signal read_back        : integer range 0 to 100000     := 0;
  96. signal read_cancel      : STD_LOGIC                     := '0';
  97.  
  98. -- current track
  99. signal current_track    : integer range 0 to 255        := 0;
  100. signal wanted_track     : integer range 0 to 255        := 0;
  101.  
  102. -- PLL internal registers:
  103. signal rdata_pulse      : STD_LOGIC                     := '0';
  104. signal last_rdata       : STD_LOGIC                     := '1';
  105. signal length           : integer range 0 to 100000     := 0;
  106. signal delay            : integer range 0 to 100000     := 0;
  107. signal skip             : integer range 0 to 100000     := 0;
  108. signal reset_front      : integer range 0 to 100000     := 0;
  109. signal reset_back       : integer range 0 to 100000     := 0;
  110. signal clock_div        : integer range 0 to 50         := 0;
  111.  
  112. -- MFM bit buffer
  113. signal mfm_front        : integer range 0 to 100000     := 0;
  114. signal mfm_back         : integer range 0 to 100000     := 0;
  115. signal mfm_type         : integer range 0 to 100000     := 0;
  116. signal mfm_counter      : integer range 0 to 100000     := 0;
  117. signal mfm_clock        : STD_LOGIC                     := '0';
  118. signal mfm_data         : STD_LOGIC                     := '0';
  119.  
  120. -- read process variables
  121. signal read_active      : STD_LOGIC                     := '0';
  122. signal rd_phase         : integer range 0 to 100000     := 0;
  123. signal rd_subphase      : integer range 0 to 100000     := 0;
  124. signal sync_count       : integer range 0 to 100000     := 0;
  125. signal sync_mark        : STD_LOGIC_VECTOR(47 downto 0) := x"448944894489";
  126. signal sync_indx        : integer range 0 to 50         := 46;
  127. signal rd_indx          : integer range 0 to 50         := 0;
  128. signal is_clock         : STD_LOGIC                     := '1';
  129. signal last_byte        : STD_LOGIC_VECTOR( 7 downto 0) := x"00";
  130. signal tmp_crc          : STD_LOGIC_VECTOR( 7 downto 0) := x"00";
  131. signal crc              : STD_LOGIC_VECTOR(15 downto 0) := x"0000";
  132. signal crc_zeros        : STD_LOGIC                     := '0';
  133.  
  134. -- FDC registers as seen by CPU:
  135. signal cylinder         : STD_LOGIC_VECTOR (7 downto 0) := x"00";
  136. signal head             : STD_LOGIC_VECTOR (7 downto 0) := x"00";
  137. signal sector           : STD_LOGIC_VECTOR (7 downto 0) := x"00";
  138. signal command          : STD_LOGIC_VECTOR (7 downto 0) := x"00";
  139.  
  140. begin
  141.  
  142. --------------------------------------------------------------------------------
  143. --                             FDD Control                                    --
  144. --------------------------------------------------------------------------------
  145.  
  146. -- translate cylinder and head registers:
  147. wanted_track <= conv_integer(unsigned(cylinder));
  148. SIDE1        <= NOT head(0);
  149.  
  150. -- translate motor state
  151. MOTEA        <= NOT motor_on;
  152. DRVSA        <= NOT motor_on;
  153.  
  154. --------------------------------------------------------------------------------
  155. --                            Buffer Access                                   --
  156. --------------------------------------------------------------------------------
  157.  
  158. process(rbuf_write)
  159. begin
  160.     if (rbuf_write = '0' and rbuf_write'event ) then
  161.         if (read_front /= read_back and read_cancel = '0') then
  162.             rbuf(rbuf_addr) <= rbuf_data;
  163.         end if;
  164.     end if;
  165. end process;
  166.  
  167. --------------------------------------------------------------------------------
  168. --                           Controller FSM                                   --
  169. --------------------------------------------------------------------------------
  170.  
  171. process (CLK_50MHz)
  172. begin
  173.     if (CLK_50MHz = '0' and CLK_50MHz'event ) then
  174.         if (phase = 0) then
  175.  
  176.             -----------------------------
  177.             -- beginning of idle state --
  178.             -----------------------------
  179.             counter  <= 0;
  180.             phase    <= 1;
  181.             STEP     <= '1';
  182.             cmd_back <= cmd_front;
  183.  
  184.         elsif (phase = 1) then
  185.  
  186.             -----------------------
  187.             -- idle state itself --
  188.             -----------------------
  189.             if (cmd_front /= cmd_back) then
  190.                 -- a command is to be executed.
  191.                 counter <= 0;
  192.                 if (command(0) = '1') then
  193.                     -- reset
  194.                     phase <= 10;
  195.                 elsif (command(1) = '1') then
  196.                     -- read
  197.                     phase <= 20;
  198.                 elsif (command(2) = '1') then
  199.                     -- write
  200.                     phase <= 30;
  201.                 else
  202.                     -- invalid
  203.                     phase <= 0;
  204.                 end if;
  205.             elsif (counter = 100000000) then
  206.                 -- it has been idle for more than 2 seconds
  207.                 motor_on <= '0';
  208.             else
  209.                 counter <= counter + 1;
  210.             end if;
  211.  
  212.         elsif (phase = 10 or phase = 20 or phase = 30) then
  213.  
  214.             ---------------
  215.             -- RUN MOTOR --
  216.             ---------------
  217.             if (counter = 0 and motor_on = '1') then
  218.                 phase    <= phase + 1;
  219.             elsif (counter = 25000000) then
  220.                 counter  <= 0;
  221.                 phase    <= phase + 1;
  222.             else
  223.                 motor_on <= '1';
  224.                 counter  <= counter + 1;
  225.             end if;
  226.  
  227.         elsif (phase = 11) then
  228.  
  229.             ----------------------
  230.             -- RESET CONTROLLER --
  231.             ----------------------
  232.             DIR <= '1'; -- from track 1 to track 0
  233.             current_track <= 0;
  234.             if (counter = 0 and TRK00 = '0') then
  235.                 phase   <= 0;
  236.             elsif (counter = 25000) then
  237.                 STEP    <= '0';
  238.                 counter <= counter + 1;
  239.             elsif (counter = 26000) then
  240.                 STEP    <= '1';
  241.                 counter <= counter + 1;
  242.             elsif (counter = 75000) then
  243.                 STEP    <= '0';
  244.                 counter <= counter + 1;
  245.             elsif (counter = 76000) then
  246.                 STEP    <= '1';
  247.                 counter <= counter + 1;
  248.             elsif (counter = 200000) then
  249.                 -- seek to next track
  250.                 counter <= 0;
  251.             else
  252.                 counter <= counter + 1;
  253.             end if;
  254.  
  255.         elsif (phase = 21 or phase = 31) then
  256.  
  257.             ----------------
  258.             -- SEEK TRACK --
  259.             ----------------
  260.             if (current_track < wanted_track) then
  261.                 DIR <= '0';
  262.             elsif (current_track > wanted_track) then
  263.                 DIR <= '1';
  264.             else
  265.                 phase <= phase + 1;
  266.             end if;
  267.             if (counter = 25000) then
  268.                 STEP    <= '0';
  269.                 counter <= counter + 1;
  270.             elsif (counter = 26000) then
  271.                 STEP    <= '1';
  272.                 counter <= counter + 1;
  273.             elsif (counter = 75000) then
  274.                 STEP    <= '0';
  275.                 counter <= counter + 1;
  276.             elsif (counter = 76000) then
  277.                 STEP    <= '1';
  278.                 counter <= counter + 1;
  279.             elsif (counter = 200000) then
  280.                 if (current_track < wanted_track) then
  281.                     current_track <= current_track + 1;
  282.                 else
  283.                     current_track <= current_track - 1;
  284.                 end if;
  285.                 counter <= 0;
  286.             else
  287.                 counter <= counter + 1;
  288.             end if;
  289.  
  290.         -----------------
  291.         -- READ SECTOR --
  292.         -----------------
  293.         elsif (phase = 22) then
  294.             phase       <= 23;
  295.             read_cancel <= '0';
  296.             read_front  <= read_front + 1;
  297.         elsif (phase = 23) then
  298.             if (read_front = read_back) then
  299.                 -- read operation done
  300.                 cmd_err <= '0';
  301.                 counter <= 0;
  302.                 phase   <= 0;
  303.             elsif (counter = 200000000) then
  304.                 -- timeout
  305.                 cmd_err     <= '1';
  306.                 read_cancel <= '1';
  307.                 counter     <= 0;
  308.                 phase       <= 0;
  309.             else
  310.                 counter <= counter + 1;
  311.             end if;
  312.         end if;
  313.  
  314.  
  315.     end if;
  316. end process;
  317.  
  318. --------------------------------------------------------------------------------
  319. --                      Digital Phase Locked Loop                             --
  320. --------------------------------------------------------------------------------
  321.  
  322. process(rdata_pulse)
  323.  
  324. -- length limits
  325. variable one_imp_low  : integer range 0 to 1000 := 0;
  326. variable one_imp_nom  : integer range 0 to 1000 := 0;
  327. variable one_imp_high : integer range 0 to 1000 := 0;
  328.  
  329. variable two_imp_low  : integer range 0 to 1000 := 0;
  330. variable two_imp_nom  : integer range 0 to 1000 := 0;
  331. variable two_imp_high : integer range 0 to 1000 := 0;
  332.  
  333. variable tre_imp_low  : integer range 0 to 1000 := 0;
  334. variable tre_imp_nom  : integer range 0 to 1000 := 0;
  335. variable tre_imp_high : integer range 0 to 1000 := 0;
  336.  
  337. -- delay:
  338. variable old_delay    : integer range 0 to 1000 := 0;
  339. variable new_delay    : integer range 0 to 1000 := 0;
  340.  
  341. variable length_snap  : integer range 0 to 1000 := 0;
  342.  
  343. begin
  344.  
  345.     if (rdata_pulse = '1' and rdata_pulse'event ) then
  346.  
  347.         if (read_front /= read_back and read_cancel = '0') then
  348.  
  349.             -- pulse edge, store delay in a variable:
  350.             old_delay    := delay;
  351.  
  352.             -- calculate limits:
  353.             one_imp_low  := old_delay-old_delay/4;
  354.             one_imp_nom  := old_delay;
  355.             one_imp_high := old_delay+old_delay/4;
  356.  
  357.             two_imp_low  := old_delay+old_delay/4;
  358.             two_imp_nom  := old_delay+old_delay/2;
  359.             two_imp_high := old_delay+old_delay-old_delay/4;
  360.  
  361.             tre_imp_low  := old_delay+old_delay-old_delay/4;
  362.             tre_imp_nom  := old_delay+old_delay;
  363.             tre_imp_high := old_delay+old_delay+old_delay/4;
  364.  
  365.             length_snap  := length;
  366.  
  367.             -- process MFM bits
  368.             if (skip > 0) then
  369.                 skip <= skip - 1;
  370.             elsif (length_snap < delay/4) then
  371.                 -- too small
  372.             elsif (length_snap < one_imp_high) then
  373.                 -- 1us between two pulses
  374.                 new_delay := old_delay - (old_delay - length_snap)/2;
  375.                 mfm_type <= 2;
  376.                 mfm_front <= mfm_front + 1;
  377.             elsif (length_snap < two_imp_high) then
  378.                 -- 1.5us between two pulses
  379.                 mfm_type <= 3;
  380.                 mfm_front <= mfm_front + 1;
  381.                 new_delay := old_delay - (old_delay-(length_snap+length_snap)/4-
  382.                                 (length_snap+length_snap)/8 +
  383.                                 (length_snap+length_snap)/32)/2;
  384.             elsif (length_snap < delay+delay+delay) then
  385.                 -- 2us between two pulses
  386.                 mfm_type <= 4;
  387.                 mfm_front <= mfm_front + 1;
  388.                 new_delay := old_delay - (old_delay - length_snap/2)/2;
  389.             else
  390.                 -- too long duration between pulses
  391.                 skip <= 5;
  392.             end if;
  393.  
  394.             -- filter and update delay:
  395.             if (new_delay > old_delay + old_delay/8) then
  396.                 delay <= old_delay + old_delay/8;
  397.             elsif (new_delay < old_delay - old_delay/8) then
  398.                 delay <= old_delay - old_delay/8;
  399.             else
  400.                 delay <= new_delay;
  401.             end if;
  402.  
  403.             -- initialize length for next pulse
  404.             reset_front <= reset_front + 1;
  405.  
  406.         else
  407.  
  408.             -- initialize skip to 1
  409.             skip       <= 1;
  410.             -- initialize delay to 100
  411.             delay      <= 100;
  412.  
  413.         end if;
  414.  
  415.     end if;
  416.  
  417. end process;
  418.  
  419. process(CLK_50MHz)
  420. begin
  421.  
  422.     if (CLK_50MHz = '1' and CLK_50MHz'event) then
  423.         if (clock_div = 7) then
  424.             clock_div <= 0;
  425.             rdata_pulse <= rdata;
  426.         else
  427.             if (clock_div = 5) then
  428.                 if (reset_front /= reset_back) then
  429.                     length <= 1;
  430.                     reset_back <= reset_front;
  431.                 else
  432.                     length <= length + 8;
  433.                 end if;
  434.             end if;
  435.             clock_div <= clock_div + 1;
  436.         end if;
  437.     end if;
  438.  
  439. end process;
  440.  
  441. --------------------------------------------------------------------------------
  442. --                     Read Command State Machine                             --
  443. --------------------------------------------------------------------------------
  444.  
  445. process(mfm_clock)
  446. begin
  447.     if (mfm_clock = '0' and mfm_clock'event ) then
  448.         if (read_front /= read_back) then
  449.             if (read_cancel = '1') then
  450.                 -- operation cancelled
  451.                 read_back   <= read_front; -- finish the deal
  452.                 read_active <= '0';
  453.                 rbuf_write  <= '0'; -- cancel any write operation
  454.             elsif (read_active = '0') then
  455.                 -- operation started
  456.                 read_active <= '1';
  457.                 rd_phase    <= 1;
  458.             else
  459.                 -- currently operating
  460.                 if (rd_phase = 1) then
  461.                     ----------------
  462.                     -- INITIALIZE --
  463.                     ----------------
  464.                     sync_indx   <= 46;
  465.                     sync_count  <= 0;
  466.                     rd_subphase <= 0;
  467.                     rd_phase    <= rd_phase + 1;
  468.                 elsif (rd_phase = 2) then
  469.                     ----------------------
  470.                     -- LOOKING FOR SYNC --
  471.                     ----------------------
  472.                     if (mfm_data = sync_mark(sync_indx)) then
  473.                         if (sync_indx > 0) then
  474.                             sync_indx  <= sync_indx - 1;
  475.                         else
  476.                             -- sync mark matched
  477.                             rd_phase   <= rd_phase + 1;
  478.                             crc        <= x"E59A"; -- initialize CRC
  479.                             crc_zeros  <= '0';
  480.                             rd_indx    <= 8;   -- will be decremented
  481.                             is_clock   <= '1'; -- next bit is a clock
  482.                         end if;
  483.                     elsif (mfm_data = sync_mark(46)) then
  484.                         sync_indx   <= 45;
  485.                     else
  486.                         sync_indx   <= 46;
  487.                     end if;
  488.                     sync_count <= sync_count + 1;
  489.                 elsif (rd_phase = 3) then
  490.                     -------------------------------
  491.                     -- READ SECTOR ADDRESS FIELD --
  492.                     -------------------------------
  493.                     if (is_clock = '1') then
  494.                         -- current bit is a clock
  495.                         is_clock   <= '0';
  496.                         if (rd_indx > 0) then
  497.                             rd_indx <= rd_indx - 1;
  498.                         else
  499.                             rd_indx <= 7;
  500.                             -- *** have just read a full byte ***
  501.                             if (rd_subphase = 0) then
  502.                                 -- should be FE
  503.                                 if (last_byte = x"FE") then
  504.                                     rd_subphase <= rd_subphase + 1;
  505.                                 else
  506.                                     rd_phase  <= 1; -- search again
  507.                                 end if;
  508.                             elsif (rd_subphase = 1) then
  509.                                 -- track
  510.                                 if (last_byte = cylinder) then
  511.                                     rd_subphase <= rd_subphase + 1;
  512.                                 else
  513.                                     rd_phase  <= 1; -- search again
  514.                                 end if;
  515.                             elsif (rd_subphase = 2) then
  516.                                 -- head
  517.                                 if (last_byte = head) then
  518.                                     rd_subphase <= rd_subphase + 1;
  519.                                 else
  520.                                     rd_phase  <= 1; -- search again
  521.                                 end if;
  522.                             elsif (rd_subphase = 3) then
  523.                                 -- sector
  524.                                 if (last_byte = sector) then
  525.                                     rd_subphase <= rd_subphase + 1;
  526.                                 else
  527.                                     rd_phase  <= 1; -- search again
  528.                                 end if;
  529.                             elsif (rd_subphase = 4) then
  530.                                 -- sector length
  531.                                 if (last_byte = x"02") then
  532.                                     rd_subphase <= rd_subphase + 1;
  533.                                     crc_zeros   <= '1';
  534.                                 else
  535.                                     rd_phase  <= 1; -- search again
  536.                                 end if;
  537.                             elsif (rd_subphase = 5) then
  538.                                 -- CRC 1
  539.                                 tmp_crc <= last_byte;
  540.                                 rd_subphase <= rd_subphase + 1;
  541.                             elsif (rd_subphase = 6) then
  542.                                 -- CRC 2
  543.                                 if ((tmp_crc & last_byte) = crc) then
  544.                                     rd_subphase <= rd_subphase + 1;
  545.                                 else
  546.                                     rd_phase  <= 1; -- search again
  547.                                 end if;
  548.                             elsif (rd_subphase = 7) then
  549.                                 -- seek to next A1 address mark
  550.                                 sync_indx   <= 46;
  551.                                 sync_count  <= 0;
  552.                                 rd_phase    <= 2;
  553.                                 rd_subphase <= rd_subphase + 1;
  554.                             elsif (rd_subphase = 8) then
  555.                                 if (sync_count > 700) then
  556.                                     rd_phase  <= 1; -- search again
  557.                                 elsif (last_byte=x"FB" or last_byte=x"F8") then
  558.                                     rd_subphase <= rd_subphase + 1;
  559.                                 else
  560.                                     rd_phase  <= 1; -- search again
  561.                                 end if;
  562.                             elsif (rd_subphase > 8 and rd_subphase < 521) then
  563.                                 rbuf_addr   <= rd_subphase-9;
  564.                                 rbuf_data   <= last_byte;
  565.                                 rbuf_write  <= '1';
  566.                                 if (rd_subphase = 520) then
  567.                                     crc_zeros <= '1';
  568.                                 end if;
  569.                                 rd_subphase <= rd_subphase + 1;
  570.                             elsif (rd_subphase = 521) then
  571.                                 -- CRC 1
  572.                                 tmp_crc     <= last_byte;
  573.                                 rd_subphase <= rd_subphase + 1;
  574.                             elsif (rd_subphase = 522) then
  575.                                 -- CRC 2
  576.                                 if ((tmp_crc & last_byte) = crc) then
  577.                                     rd_subphase <= rd_subphase + 1;
  578.                                 else
  579.                                     rd_phase  <= 1; -- search again
  580.                                 end if;
  581.                             elsif (rd_subphase = 523) then
  582.                                 -- finally done
  583.                                 read_back   <= read_front;
  584.                                 read_active <= '0';
  585.                             end if;
  586.                         end if;
  587.                     else
  588.                         -- read data bit
  589.                         last_byte(rd_indx) <= mfm_data;
  590.                         -- calculate CRC
  591.                         if (crc_zeros = '0') then
  592.                             if (crc(15) = '1') then
  593.                                 crc <= (crc(14 downto 0)&mfm_data) XOR x"1021";
  594.                             else
  595.                                 crc <= (crc(14 downto 0)&mfm_data);
  596.                             end if;
  597.                         else
  598.                             if (crc(15) = '1') then
  599.                                 crc <= (crc(14 downto 0)&"0") XOR x"1021";
  600.                             else
  601.                                 crc <= (crc(14 downto 0)&"0");
  602.                             end if;
  603.                         end if;
  604.                         -- next bit is a clock
  605.                         is_clock   <= '1';
  606.                         -- stop any writing to rbuf
  607.                         rbuf_write <= '0';
  608.                     end if;
  609.                 end if;
  610.             end if;
  611.         end if;
  612.     end if;
  613. end process;
  614.  
  615. process(CLK_50MHz)
  616. begin
  617.     if (CLK_50MHz = '1' and CLK_50MHz'event ) then
  618.         if (mfm_back /= mfm_front) then
  619.             if (mfm_counter = 0) then
  620.                 mfm_data  <= '1';
  621.                 mfm_clock <= '1';
  622.             elsif (mfm_counter = 1) then
  623.                 mfm_clock <= '0';
  624.             elsif (mfm_counter = 2) then
  625.                 mfm_data  <= '0';
  626.                 mfm_clock <= '1';
  627.             elsif (mfm_counter = 3) then
  628.                 mfm_clock <= '0';
  629.             elsif (mfm_counter = 4) then
  630.                 mfm_clock <= '1';
  631.             elsif (mfm_counter = 5) then
  632.                 mfm_clock <= '0';
  633.             elsif (mfm_counter = 6) then
  634.                 mfm_clock <= '1';
  635.             elsif (mfm_counter = 7) then
  636.                 mfm_clock <= '0';
  637.             end if;
  638.             if (mfm_counter = mfm_type*2 - 1) then
  639.                 mfm_back    <= mfm_front;
  640.                 mfm_counter <= 0;
  641.             else
  642.                 mfm_counter <= mfm_counter + 1;
  643.             end if;
  644.         else
  645.             mfm_counter <= 0;
  646.             mfm_clock   <= '0';
  647.         end if;
  648.     end if;
  649. end process;
  650.  
  651. --------------------------------------------------------------------------------
  652. --                           CPU Interface                                    --
  653. --------------------------------------------------------------------------------
  654.  
  655. process (CLK_50MHz)
  656. begin
  657.     if (CLK_50MHz = '0' and CLK_50MHz'event) then
  658.         if (CS = '1') then
  659.             if (A = "000" and WR = '1') then
  660.                 -- cylinder register
  661.                 cylinder <= Din;
  662.             elsif (A = "001" and WR = '1') then
  663.                 -- head register
  664.                 head     <= Din;
  665.             elsif (A = "010" and WR = '1') then
  666.                 -- sector register
  667.                 sector   <= Din;
  668.             elsif (A = "011" and WR = '1') then
  669.                 -- command register
  670.                 command   <= Din;
  671.                 cmd_front <= cmd_front + 1;
  672.                 rbuf_ptr  <= 0;
  673.             elsif (A = "100" and RD = '1') then
  674.                 -- status register
  675.                 if (cmd_front = cmd_back) then
  676.                     Dout(0) <= '0'; -- not busy
  677.                 else
  678.                     Dout(0) <= '1'; -- busy
  679.                 end if;
  680.                 Dout(1)          <= cmd_err;
  681.                 Dout(7 downto 2) <= "000000";
  682.             elsif (A = "101" and RD = '1') then
  683.                 -- data out
  684.                 Dout <= rbuf(rbuf_ptr);
  685.             elsif (A = "110" and WR = '1') then
  686.                 -- data in
  687.             elsif (A = "111" and WR = '1') then
  688.                 -- update pointer
  689.                 if (rbuf_ptr = 511) then
  690.                     rbuf_ptr <= 0;
  691.                 else
  692.                     rbuf_ptr <= rbuf_ptr + 1;
  693.                 end if;
  694.             end if;
  695.         end if;
  696.     end if;
  697. end process;
  698.  
  699. end Behavioral;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement