Created
December 15, 2016 02:29
-
-
Save insom/f837035a2034fe94c42bde58ae88ec99 to your computer and use it in GitHub Desktop.
VHDL file for my Microcomputer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| library ieee; | |
| use ieee.std_logic_1164.all; | |
| use IEEE.STD_LOGIC_ARITH.all; | |
| use IEEE.STD_LOGIC_UNSIGNED.all; | |
| -- | |
| -- This defines the actual physical inputs and outputs I'm going to use. | |
| -- | |
| entity Microcomputer is | |
| port( | |
| n_reset : in std_logic; | |
| clk : in std_logic; | |
| rxd1 : in std_logic; | |
| txd1 : out std_logic; | |
| leds : out std_logic_vector(7 downto 0) | |
| ); | |
| end Microcomputer; | |
| -- | |
| -- This section defines signals, where are like the inputs and outputs of the module. | |
| -- | |
| architecture struct of Microcomputer is | |
| signal n_WR : std_logic; | |
| signal n_RD : std_logic; | |
| signal cpuAddress : std_logic_vector(15 downto 0); | |
| signal cpuDataOut : std_logic_vector(7 downto 0); | |
| signal cpuDataIn : std_logic_vector(7 downto 0); | |
| signal basRomData : std_logic_vector(7 downto 0); | |
| signal internalRam1DataOut : std_logic_vector(7 downto 0); | |
| signal internalRam2DataOut : std_logic_vector(7 downto 0); | |
| signal interface1DataOut : std_logic_vector(7 downto 0); | |
| signal n_memWR : std_logic :='1'; | |
| signal n_memRD : std_logic :='1'; | |
| signal n_ioWR : std_logic :='1'; | |
| signal n_ioRD : std_logic :='1'; | |
| signal n_MREQ : std_logic :='1'; | |
| signal n_IORQ : std_logic :='1'; | |
| signal n_int1 : std_logic :='1'; | |
| signal n_int2 : std_logic :='1'; | |
| signal n_internalRam1CS : std_logic :='1'; | |
| signal n_internalRam2CS : std_logic :='1'; | |
| signal n_basRomCS : std_logic :='1'; | |
| signal n_interface1CS : std_logic :='1'; | |
| signal n_aaronCS : std_logic :='1'; | |
| signal serialClkCount : std_logic_vector(15 downto 0); | |
| signal cpuClkCount : std_logic_vector(5 downto 0); | |
| signal cpuClock : std_logic; | |
| signal serialClock : std_logic; | |
| begin | |
| -- | |
| -- These entities are like importing other VHDL modules. | |
| -- The map() section maps the signals listed on _those_ VHDL modules to our | |
| -- own signals or to pins. | |
| -- | |
| cpu1 : entity work.t80s | |
| generic map(mode => 1, t2write => 1, iowait => 0) | |
| port map( | |
| reset_n => n_reset, | |
| clk_n => cpuClock, | |
| wait_n => '1', | |
| int_n => '1', | |
| nmi_n => '1', | |
| busrq_n => '1', | |
| mreq_n => n_MREQ, | |
| iorq_n => n_IORQ, | |
| rd_n => n_RD, | |
| wr_n => n_WR, | |
| a => cpuAddress, | |
| di => cpuDataIn, | |
| do => cpuDataOut | |
| ); | |
| rom1 : entity work.Z80_BASIC_ROM -- 8KB BASIC | |
| port map( | |
| address => cpuAddress(12 downto 0), | |
| clock => clk, | |
| q => basRomData | |
| ); | |
| ram1: entity work.InternalRam4K | |
| port map( | |
| address => cpuAddress(11 downto 0), | |
| clock => clk, | |
| data => cpuDataOut, | |
| wren => not(n_memWR or n_internalRam1CS), | |
| q => internalRam1DataOut | |
| ); | |
| io1 : entity work.bufferedUART | |
| port map( | |
| clk => clk, | |
| n_wr => n_interface1CS or n_ioWR, | |
| n_rd => n_interface1CS or n_ioRD, | |
| n_int => n_int1, | |
| regSel => cpuAddress(0), | |
| dataIn => cpuDataOut, | |
| dataOut => interface1DataOut, | |
| rxClock => serialClock, | |
| txClock => serialClock, | |
| rxd => rxd1, | |
| txd => txd1, | |
| n_cts => '0', | |
| n_dcd => '0' | |
| ); | |
| io2 : entity work.aaron | |
| port map( | |
| n_wr => n_aaronCS or n_ioWR, | |
| dataIn => cpuDataOut, | |
| dataOut => leds, | |
| reset_n => n_reset | |
| ); | |
| n_ioWR <= n_WR or n_IORQ; | |
| n_memWR <= n_WR or n_MREQ; | |
| n_ioRD <= n_RD or n_IORQ; | |
| n_memRD <= n_RD or n_MREQ; | |
| -- | |
| -- This section performs the actual address decoding - it will raise or lower | |
| -- the chip select lines of the modules depending on the contents of the address | |
| -- bus. | |
| -- | |
| -- These are active low so '0' means "enable this CS line" | |
| n_basRomCS <= '0' when cpuAddress(15 downto 13) = "000" else '1'; -- 8K at bottom of memory | |
| n_internalRam1CS <= '0' when cpuAddress(15 downto 12) = "0010" else '1'; -- 4K above that | |
| n_interface1CS <= '0' when cpuAddress(7 downto 1) = "1000000" and (n_ioWR='0' or n_ioRD = '0') else '1'; -- 2 Bytes $80-$81 | |
| n_aaronCS <= '0' when cpuAddress(7 downto 1) = "1001000" and (n_ioWR='0' or n_ioRD = '0') else '1'; -- 2 Bytes $90-$91 | |
| -- Connect the CPU and peripheral data lines when the respective CS line is low | |
| cpuDataIn <= | |
| interface1DataOut when n_interface1CS = '0' else | |
| basRomData when n_basRomCS = '0' else | |
| internalRam1DataOut when n_internalRam1CS= '0' else | |
| x"FF"; | |
| -- | |
| -- This is all to create a secondary, slower, clock for the UART to use. | |
| -- | |
| serialClock <= serialClkCount(15); | |
| process (clk) | |
| begin | |
| if rising_edge(clk) then | |
| if cpuClkCount < 4 then -- 4 = 10MHz, 3 = 12.5MHz, 2=16.6MHz, 1=25MHz | |
| cpuClkCount <= cpuClkCount + 1; | |
| else | |
| cpuClkCount <= (others=>'0'); | |
| end if; | |
| if cpuClkCount < 2 then -- 2 when 10MHz, 2 when 12.5MHz, 2 when 16.6MHz, 1 when 25MHz | |
| cpuClock <= '0'; | |
| else | |
| cpuClock <= '1'; | |
| end if; | |
| -- Serial clock DDS | |
| -- 50MHz master input clock: | |
| -- Baud Increment | |
| -- 115200 2416 | |
| -- 38400 805 | |
| -- 19200 403 | |
| -- 9600 201 | |
| -- 4800 101 | |
| -- 2400 50 | |
| serialClkCount <= serialClkCount + 2416; | |
| end if; | |
| end process; | |
| end; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment