home *** CD-ROM | disk | FTP | other *** search
/ CBM Funet Archive / cbm-funet-archive-2003.iso / cbm / documents / projects / memory / c64 / rec.vhdl < prev    next >
Encoding:
Text File  |  2001-09-19  |  7.9 KB  |  398 lines

  1. -- csg reu/rec COMPATIBLE ram EXPANSION CONTROLLER
  2. -- INITIAL VERSION: 2.9.2001 BY rAINER bUCHTY (RAINER@BUCHTY.NET)
  3. --
  4. -- 16mb dram TO 64Kb c64 MEMORY dma UNIT
  5.  
  6. LIBRARY ieee;
  7. USE ieee.STD_LOGIC_1164.ALL;
  8. USE ieee.STD_LOGIC_ARITH.ALL;
  9. USE ieee.STD_LOGIC_UNSIGNED.ALL;
  10.  
  11. COMPONENT REC IS
  12. PORT(
  13. PHI2, DOTCLK:IN STD_LOGIC;
  14. RST:IN STD_LOGIC;
  15.  
  16. DMA:OUT STD_LOGIC;
  17. BA:IN STD_LOGIC;
  18.  
  19. CPU_ADDR:INOUT STD_LOGIC_VECTOR(15 DOWNTO 0);
  20. CPU_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
  21. CPU_RW:INOUT STD_LOGIC;
  22.  
  23. REU_ADDR:OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
  24. REU_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
  25. REU_RW:OUT STD_LOGIC;
  26. REU_RAS,
  27. REU_CAS:OUT STD_LOGIC;
  28.  
  29. SIZE:IN STD_LOGIC;
  30.  
  31. AEC:INOUT STD_LOGIC;
  32. BA:INOUT STD_LOGIC
  33. );
  34. END COMPONENT;
  35.  
  36. -- --------------------------------------------------------------------------
  37.  
  38. LIBRARY ieee;
  39. USE ieee.STD_LOGIC_1164.ALL;
  40. USE ieee.STD_LOGIC_ARITH.ALL;
  41. USE ieee.STD_LOGIC_UNSIGNED.ALL;
  42.  
  43. ENTITY REC IS
  44. PORT(
  45. PHI2, DOTCLK:IN STD_LOGIC;
  46. RST:IN STD_LOGIC;
  47.  
  48. DMA:OUT STD_LOGIC;
  49. BA:IN STD_LOGIC;
  50.  
  51. CPU_ADDR:INOUT STD_LOGIC_VECTOR(15 DOWNTO 0);
  52. CPU_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
  53. CPU_RW:INOUT STD_LOGIC;
  54.  
  55. REU_ADDR:OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
  56. REU_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
  57. REU_RW:OUT STD_LOGIC;
  58. REU_RAS,
  59. REU_CAS:OUT STD_LOGIC;
  60.  
  61. SIZE:IN STD_LOGIC;
  62.  
  63. AEC:INOUT STD_LOGIC;
  64. BA:INOUT STD_LOGIC
  65. );
  66. END ENTITY;
  67.  
  68. -- --------------------------------------------------------------------------
  69.  
  70. ARCHITECTURE ARCH_REC OF REC IS
  71.  
  72. -- acr AND imr
  73. SIGNAL ACR: STD_LOGIC_VECTOR(1 DOWNTO 0);
  74. SIGNAL IMR: STD_LOGIC_VECTOR(2 DOWNTO 0);
  75.  
  76. -- cr
  77. SIGNAL EXECUTE, LOAD, FF00:STD_LOGIC;
  78. SIGNAL TT:STD_LOGIC_VECTOR(1 DOWNTO 0);
  79.  
  80. -- sr
  81. SIGNAL IP, EOB, FAULT: STD_LOGIC_VECTOR;
  82. CONSTANT VERSION: STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
  83.  
  84. -- MAIN STATE MACHINE
  85. SIGNAL STATE: STD_LOGIC_VECTOR(3 DOWNTO 0);
  86.  
  87. -- TRANSFER CONTROL
  88. SIGNAL BASE_REU, SADR_REU: STD_LOGIC_VECTOR(23 DOWNTO 0);
  89. SIGNAL BASE_C64, SADR_C64: STD_LOGIC_VECTOR(15 DOWNTO 0);
  90. SIGNAL XFER_CNT, XFER_LEN: STD_LOGIC_VECTOR(15 DOWNTO 0);
  91.  
  92. -- swap STORAGE
  93. SIGNAL REU_STORE, CPU_STORE:STD_LOGIC_VECTOR(7 DOWNTO 0);
  94.  
  95. -- MISC
  96. SIGNAL REF_CNT:STD_LOGIC_VECTOR(11 DOWNTO 0);-- REFRESH COUNTER
  97. SIGNAL EXEC_S:STD_LOGIC;-- EXEC SAMPLED
  98. SIGNAL BA_S:STD_LOGIC;-- BA SAMPLED
  99. SIGNAL SCNT:STD_LOGIC;-- swap STATE
  100.  
  101. BEGIN
  102.  
  103. -- --------------------------------------------------------------------------  
  104. -- dma TRANSFER
  105. -- --------------------------------------------------------------------------  
  106. PROCESS(DOTCLK,RST)
  107. BEGIN
  108. IF RST='0' THEN
  109. BASE_REU<="000000000000000000000000";
  110. BASE_C64<="0000000000000000";
  111. XFER_CNT<="0000000000000000";
  112.  
  113. REF_CNT<="000000000000";
  114.  
  115. REU_RAS<='1';
  116. REU_CAS<='1';
  117. REU_RW<='1';
  118. CPU_RW<='z';
  119.  
  120. EXEC_S<='0';
  121. BA_S<=BA;
  122.  
  123. STATE<="000";
  124. SCNT<='0';
  125.  
  126. -- RISING EDGE: ram ADDRESSING & DATA TRANSFER
  127. ELSIF RISING'EDGE(DOTCLK) THEN
  128. BA_S<=BA;
  129.  
  130. -- MUTE C64 LINES BY DEFAULT
  131. CPU_ADDR<="zzzzzzzzzzzzzzzz";
  132. CPU_DATA<="zzzzzzzz";
  133. CPU_RW<='z';
  134.  
  135. -- TRANSFER CONTROL REGISTERS WHILE IDLE
  136. IF EXEC_S='0' THEN
  137. BASE_REU<=SADR_REU;
  138. BASE_C64<=SADR_C64;
  139. XFER_CNT<=XFER_LEN;
  140.  
  141. EXEC_S<=EXECUTE;
  142. SCNT<='0';
  143.  
  144. -- MEMORY ACCESS
  145. ELSE IF BA='1' THEN
  146. CASE STATE IS
  147. WHEN "000" =>-- APPLY ROW ADDR
  148. REU_ADDR<=BASE_REU(11 DOWNTO 0);
  149. CPU_ADDR<=BASE_C64;
  150.  
  151. WHEN "001" =>-- APPLY COL ADDR
  152. REU_ADDR<=BASE_REU(23 DOWNTO 12);
  153. CPU_ADDR<=BASE_C64;
  154.  
  155. WHEN "010" =>-- TRANSFER DATA
  156. CPU_ADDR<=BASE_C64;
  157.  
  158. FAULT<='0';
  159.  
  160. CASE TT IS
  161. WHEN "00" =>-- c64->reu
  162. REU_DATA<=CPU_DATA;
  163.  
  164. WHEN "01" =>-- reu->c64
  165. CPU_DATA<=REU_DATA;
  166.  
  167. WHEN "10" =>-- swap
  168. IF SCNT='0' THEN
  169. REU_STORE<=CPU_DATA;
  170. CPU_STORE<=REU_DATA;
  171. ELSE
  172. REU_DATA<=REU_STORE;
  173. CPU_DATA<=CPU_STORE;
  174. END IF;
  175.  
  176. SCNT<=NOT(SCNT);
  177.  
  178. WHEN "11" =>-- verify
  179. IF CPU_DATA/=REU_DATA
  180. FAULT<='1';
  181. END IF;
  182.  
  183. WHEN OTHERS =>
  184. NULL;
  185.  
  186. END CASE;
  187.  
  188. WHEN "011" =>-- INC ADDRESSES, DEC COUNTER
  189. XFER_CNT<=XFER_CNT-1;
  190.  
  191. IF ACR(0)='1' THEN
  192. BASE_REU<=BASE_REU+1;
  193. END IF;
  194.  
  195. IF ACR(0)='1' THEN
  196. BASE_C64<=BASE_C64+1;
  197. END IF;
  198.  
  199.  
  200. WHEN "100" =>-- cbr #1
  201. REU_ADDR<=REF_CNT;
  202.  
  203. WHEN "101" =>-- cbr #2
  204. REU_ADDR<="000000000000";
  205.  
  206. WHEN "111" =>-- FINISH/RELOAD
  207. REF_CNT<=REF_CNT+1;
  208.  
  209. IF XFER_CNT=0 THEN
  210. IF RELOAD='1' THEN
  211. BASE_REU<=SADR_REU;
  212. BASE_C64<=SADR_C64;
  213. XFER_CNT<=XFER_LEN;
  214. END IF;
  215.  
  216. EOB<='1';
  217. EXEC_S<='0';
  218. END IF;
  219.  
  220. WHEN OTHERS =>
  221. NULL;
  222.  
  223. END CASE;
  224. END IF;
  225.  
  226. -- FALLING EDGE: ram CONTROL
  227. ELSIF FALLING'EDGE(DOTCLK) THEN
  228. -- ram CONTROL DEFAULTS
  229. CPU_RW<='1';
  230. REU_RW<='1';
  231. REU_RAS<='1';
  232. REU_CAS<='1';
  233.  
  234. IF EXEC_S='1' AND BA_S<='1' THEN
  235. STATE<=STATE+1;
  236.  
  237. -- ram CONTROL STATE MACHINE
  238. CASE STATE IS
  239. WHEN "000" =>-- SAMPLE ROW ADDR
  240. REU_RAS<='0';
  241. REU_CAS<='1';
  242.  
  243. WHEN "001" =>-- SAMPLE COL ADDR
  244. REU_RAS<='0';
  245. REU_CAS<='0';
  246.  
  247. WHEN "010" =>-- DATA WRITE
  248. REU_RAS<='0';
  249. REU_CAS<='0';
  250.  
  251. CASE TT IS
  252. WHEN "00" =>-- c64->reu
  253. REU_RW<='0';
  254. WHEN "01" =>-- reu->c64
  255. CPU_RW<='0';
  256. WHEN "10" =>-- swap
  257. IF SCNT='1' THEN
  258. CPU_RW<='0';
  259. REU_RW<='0';
  260. END IF;
  261. WHEN OTHERS =>
  262. NULL;
  263.  
  264. END CASE;
  265.  
  266. WHEN "011" =>-- END OF TRANSFER
  267. REU_RAS<='1';
  268. REU_CAS<='0';
  269.  
  270. WHEN "100" => -- cbr #1
  271. REU_RAS<='1';
  272. REU_CAS<='0';
  273.  
  274. WHEN "101" =>-- cbr #2
  275. REU_RAS<='0';
  276. REU_CAS<='0';
  277.  
  278. WHEN OTHERS =>
  279. REU_RAS<='1';
  280. REU_CAS<='1';
  281.  
  282. END CAS-E;
  283. END IF;
  284. END IF;
  285. END PROCESS;
  286.  
  287.  
  288. -- --------------------------------------------------------------------------  
  289. -- EXTERNAL ACCESS TO reu REGISTERS
  290. -- --------------------------------------------------------------------------  
  291. REG_ACCESS:
  292. PROCESS(PHI2,RST)
  293. BEGIN
  294. VARIABLE REG_ADDR: STD_LOGIC_VECTOR(3 DOWNTO 0);
  295.  
  296. IF RST='0' THEN
  297. EXECUTE<='0';
  298. LOAD<='0';
  299. FF00<='0';
  300.  
  301. SADR_C64<="0000000000000000";
  302. SADR_REU<="000000000000000000000000";
  303. XFER_LEN<="0000000000000000";
  304.  
  305. IMR<="000";
  306. ACR<="00";
  307.  
  308. ELSIF (PHI2'EVENT AND PHI2='1') THEN
  309. REG_ADDR:=CPU_ADR(3 DOWNTO 0);
  310.  
  311. -- CLEAR EXECUTE WHEN FINISHED
  312. IF EXEC_S='1' AND EXECUTE='1' THEN
  313. EXECUTE<='0';
  314.  
  315. -- AUTO-EXECUTE ON FF00 ACCESS
  316. ELSIF LOAD='1' AND CPU_ADR="1111111100000000" THEN
  317. EXECUTE<='1';
  318.  
  319. -- NORMAL ACCESS
  320. ELSIF CPU_RW='0' THEN
  321.  
  322. CASE REG_ADDR IS
  323.  
  324. WHEN "0001" =>-- cr
  325. EXECUTE<=CPU_DBUS(7);
  326. LOAD<=CPU_DBUS(5);
  327. FF00<=CPU_DBUS(4);
  328. TT<=CPU_DBUS(1 DOWNTO 0);
  329.  
  330. WHEN "0010" =>-- C64 START ADDRESS
  331. SADR_C64(15 DOWNTO  8)<=CPU_DBUS;
  332. WHEN "0011" =>
  333. SADR_C64( 7 DOWNTO  0)<=CPU_DBUS;
  334.  
  335. WHEN "0100" =>-- REU START ADDRESS
  336. SADR_REU(23 DOWNTO 16)<=CPU_DBUS;
  337. WHEN "0101" =>
  338. SADR_REU(16 DOWNTO  8)<=CPU_DBUS;
  339. WHEN "0110" =>
  340. SADR_REU( 7 DOWNTO  0)<=CPU_DBUS;
  341.  
  342. WHEN "0111" =>-- TRANSFER LENGTH
  343. XFER_LEN(15 DOWNTO  8)<=CPU_DBUS;
  344. WHEN "1000" =>
  345. XFER_LEN( 7 DOWNTO  0)<=CPU_DBUS;
  346.  
  347. WHEN "1001" =>-- imr
  348. IMR<=CPU_DBUS(7 DOWNTO 5);
  349.  
  350. WHEN "1010" =>-- acr
  351. ACR<=CPU_DBUS(7 DOWNTO 6);
  352.  
  353. WHEN OTHERS =>
  354. NULL;
  355.  
  356. END CASE;
  357.  
  358. ELSIF CPU_RW='1' THEN
  359. CASE REG_ADDR IS
  360. WHEN "0000" =>-- sr
  361. CPU_DBUS<=IP & EOB & FAULT & SIZE & VERSION;
  362.  
  363. WHEN "0001" =>-- cr
  364. CPU_DBUS<=EXECUTE & '1' & LOAD & FF00 & "11" & TT;
  365.  
  366. WHEN "0010" =>-- C64 START ADDRESS 
  367. CPU_DBUS<=SADR_C64(15 DOWNTO  8);
  368. WHEN "0011" =>
  369. CPU_DBUS<=SADR_C64( 7 DOWNTO  0);
  370.  
  371. WHEN "0100" =>-- REU START ADDRESS
  372. CPU_DBUS<=SADR_REU(23 DOWNTO 16);
  373. WHEN "0101" =>
  374. CPU_DBUS<=SADR_REU(15 DOWNTO  8);
  375. WHEN "0110" =>
  376. CPU_DBUS<=SADR_REU( 7 DOWNTO  0);
  377.  
  378. WHEN "0111" =>-- TRANSFER LENGTH
  379. CPU_DBUS<=XFER_LEN(15 DOWNTO  8);
  380. WHEN "1000" =>
  381. CPU_DBUS<=XFER_LEN( 7 DOWNTO  0);
  382.  
  383. WHEN "1001" =>-- imr
  384. CPU_DBUS<=IMR & "11111";
  385.  
  386. WHEN "1010" =>-- acr
  387. CPU_DBUS<=ACR & "111111";
  388.  
  389. WHEN OTHERS =>
  390. NULL;
  391.  
  392. END CASE;
  393. END IF;
  394. END IF;
  395. END PROCESS;
  396.  
  397.  
  398. END ARCHITECTURE;