Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
| 1 | -- TITLE: Plasma (CPU core with memory) |
| 2 | -- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
| 3 | -- DATE CREATED: 6/4/02 |
| 4 | -- FILENAME: plasma.vhd |
| 5 | -- PROJECT: Plasma CPU core |
| 6 | -- COPYRIGHT: Software placed into the public domain by the author. |
| 7 | -- Software 'as is' without warranty. Author liable for nothing. |
| 8 | -- DESCRIPTION: |
| 9 | -- This entity combines the CPU core with memory and a UART. |
| 10 | -- |
| 11 | -- Memory Map: |
| 12 | -- 0x00000000 - 0x0000ffff Internal RAM (8KB) |
| 13 | -- 0x10000000 - 0x100fffff External RAM (1MB) |
| 14 | -- Access all Misc registers with 32-bit accesses |
| 15 | -- 0x20000000 Uart Write (will pause CPU if busy) |
| 16 | -- 0x20000000 Uart Read |
| 17 | -- 0x20000010 IRQ Mask |
| 18 | -- 0x20000020 IRQ Status |
| 19 | -- 0x20000030 Peripheric 1 |
| 20 | -- 0x20000040 Peripheric 2 |
| 21 | -- 0x20000050 Peripheric 3 |
| 22 | -- 0x20000060 Peripheric 4 |
| 23 | -- IRQ bits: |
| 24 | -- 1 ^UartWriteBusy |
| 25 | -- 0 UartDataAvailable |
| 26 | --------------------------------------------------------------------- |
| 27 | library ieee; |
| 28 | use ieee.std_logic_1164.all; |
| 29 | use ieee.numeric_std.all; |
| 30 | use work.mlite_pack.all; |
| 31 | |
| 32 | entity plasma is |
| 33 | generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM"; |
| 34 | log_file : string := "UNUSED"); |
| 35 | port(clk_in : in std_logic; |
| 36 | rst_in : in std_logic; |
| 37 | uart_write : out std_logic; |
| 38 | uart_read : in std_logic; |
| 39 | addr : in std_logic_vector(12 downto 0); |
| 40 | sram_data : in std_logic_vector(7 downto 0); |
| 41 | nwe : in std_logic; |
| 42 | noe : in std_logic; |
| 43 | ncs : in std_logic; |
| 44 | irq_pin : out std_logic; |
| 45 | led : out std_logic |
| 46 | ); |
| 47 | end; --entity plasma |
| 48 | |
| 49 | architecture logic of plasma is |
| 50 | signal reset : std_logic; |
| 51 | signal clk : std_logic; |
| 52 | signal address_next : std_logic_vector(31 downto 2); |
| 53 | signal byte_we_next : std_logic_vector(3 downto 0); |
| 54 | signal cpu_address : std_logic_vector(31 downto 0); |
| 55 | signal cpu_byte_we : std_logic_vector(3 downto 0); |
| 56 | signal cpu_data_w : std_logic_vector(31 downto 0); |
| 57 | signal cpu_data_r : std_logic_vector(31 downto 0); |
| 58 | signal cpu_pause : std_logic; |
| 59 | |
| 60 | signal bus_dec : std_logic_vector(6 downto 0); |
| 61 | |
| 62 | signal data_read_uart : std_logic_vector(7 downto 0); |
| 63 | signal data_read_pic : std_logic_vector(7 downto 0); |
| 64 | signal write_enable : std_logic; |
| 65 | signal mem_busy : std_logic; |
| 66 | |
| 67 | signal cs_pher : std_logic; |
| 68 | signal cs_uart : std_logic; |
| 69 | signal cs_pic : std_logic; |
| 70 | signal cs_p1 : std_logic; |
| 71 | signal cs_p2 : std_logic; |
| 72 | signal cs_p3 : std_logic; |
| 73 | signal cs_p4 : std_logic; |
| 74 | |
| 75 | signal uart_write_busy : std_logic; |
| 76 | signal uart_data_avail : std_logic; |
| 77 | signal irq_mask_reg : std_logic_vector(7 downto 0); |
| 78 | signal irq_status : std_logic_vector(7 downto 0); |
| 79 | signal irq : std_logic; |
| 80 | |
| 81 | signal cs_ram : std_logic; |
| 82 | signal ram_byte_we : std_logic_vector(3 downto 0); |
| 83 | signal ram_address : std_logic_vector(31 downto 2); |
| 84 | signal ram_data_w : std_logic_vector(31 downto 0); |
| 85 | signal ram_data_r : std_logic_vector(31 downto 0); |
| 86 | |
| 87 | |
| 88 | begin |
| 89 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 90 | -- CLOCK DIVIDER |
| 91 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 92 | led <= not(rst_in); |
| 93 | reset <= not(rst_in); |
| 94 | irq_pin <= not(rst_in); |
| 95 | |
| 96 | clk_div: process(reset, clk, clk_in) |
| 97 | begin |
| 98 | if reset = '1' then |
| 99 | clk <= '0'; |
| 100 | elsif rising_edge(clk_in) then |
| 101 | clk <= not clk; |
| 102 | end if; |
| 103 | end process; |
| 104 | |
| 105 | write_enable <= '1' when cpu_byte_we /= "0000" else '0'; |
| 106 | cpu_pause <= (uart_write_busy and cs_uart and write_enable); |
| 107 | |
| 108 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 109 | -- PROCESSOR |
| 110 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 111 | u1_cpu: mlite_cpu |
| 112 | generic map (memory_type => memory_type) |
| 113 | PORT MAP ( |
| 114 | clk => clk, |
| 115 | reset_in => reset, |
| 116 | intr_in => irq, |
| 117 | address_next => address_next, --before rising_edge(clk) |
| 118 | byte_we_next => byte_we_next, |
| 119 | address => cpu_address(31 downto 2), --after rising_edge(clk) |
| 120 | byte_we => cpu_byte_we, |
| 121 | data_w => cpu_data_w, |
| 122 | data_r => cpu_data_r, |
| 123 | mem_pause => cpu_pause); |
| 124 | |
| 125 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 126 | -- ADDRESS DECODER |
| 127 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 128 | cpu_address(1 downto 0) <= "00"; |
| 129 | |
| 130 | addr_decoder: process (cpu_address) |
| 131 | variable addr_dec : std_logic_vector(6 downto 0); |
| 132 | begin |
| 133 | addr_dec := cpu_address(30 downto 28) & cpu_address(7 downto 4); |
| 134 | case addr_dec is |
| 135 | when "0100000" => cs_uart <= '1'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; |
| 136 | when "0100001" => cs_uart <= '0'; cs_pic <= '1'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; |
| 137 | when "0100010" => cs_uart <= '0'; cs_pic <= '1'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; |
| 138 | when "0100011" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '1'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; |
| 139 | when "0100100" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '1'; cs_p3 <= '0'; cs_p4 <= '0'; |
| 140 | when "0100101" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '1'; cs_p4 <= '0'; |
| 141 | when "0100110" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '1'; |
| 142 | when others => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; |
| 143 | end case; |
| 144 | end process; |
| 145 | |
| 146 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 147 | -- BUS MULTIPLEXOR |
| 148 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 149 | bus_mux: process (cpu_address, ram_data_r, data_read_uart, data_read_pic) |
| 150 | variable bus_dec : std_logic_vector(4 downto 0); |
| 151 | begin |
| 152 | bus_dec := cpu_address(29) & cpu_address(7 downto 4); |
| 153 | case bus_dec is |
| 154 | when "00000" | "00001" | "00010" | "00011" | "00100" | "00101" | "00110" | "00111" | |
| 155 | "01000" | "01001" | "01010" | "01011" | "01100" | "01101" | "01110" | "01111" |
| 156 | => cpu_data_r <= ram_data_r; |
| 157 | when "10000" => cpu_data_r <= ZERO(31 downto 8) & data_read_uart; |
| 158 | when "10001" => cpu_data_r <= ZERO(31 downto 8) & data_read_pic; |
| 159 | when "10010" => cpu_data_r <= ZERO(31 downto 8) & data_read_pic; |
| 160 | when "10011" => cpu_data_r <= ZERO; |
| 161 | when "10100" => cpu_data_r <= ZERO; |
| 162 | when "10101" => cpu_data_r <= ZERO; |
| 163 | when "10110" => cpu_data_r <= ZERO; |
| 164 | when others => cpu_data_r <= ZERO; |
| 165 | end case; |
| 166 | -- end if; |
| 167 | end process; |
| 168 | |
| 169 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 170 | -- PIC |
| 171 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 172 | pic_proc: process(clk, reset, cpu_address, cs_pic, cpu_pause, cpu_byte_we, irq_mask_reg, irq_status, cpu_data_w, |
| 173 | uart_write_busy, uart_data_avail) |
| 174 | begin |
| 175 | |
| 176 | irq_status <= ZERO(5 downto 0) & not uart_write_busy & uart_data_avail; |
| 177 | |
| 178 | if cs_pic = '1' and cpu_byte_we = "0000" then |
| 179 | case cpu_address(5 downto 4) is |
| 180 | when "01" => data_read_pic <= irq_mask_reg; |
| 181 | when "10" => data_read_pic <= irq_status; |
| 182 | when others => data_read_pic <= ZERO(7 downto 0); |
| 183 | end case; |
| 184 | end if; |
| 185 | |
| 186 | if reset = '1' then |
| 187 | irq_mask_reg <= ZERO(7 downto 0); |
| 188 | elsif rising_edge(clk) then |
| 189 | if cpu_pause = '0' then |
| 190 | if cs_pic = '1' and cpu_byte_we = "1111" then |
| 191 | if cpu_address(6 downto 4) = "001" then |
| 192 | irq_mask_reg <= cpu_data_w(7 downto 0); |
| 193 | end if; |
| 194 | end if; |
| 195 | end if; |
| 196 | end if; |
| 197 | |
| 198 | if (irq_status and irq_mask_reg) /= ZERO(7 downto 0) then |
| 199 | irq <= '1'; |
| 200 | else |
| 201 | irq <= '0'; |
| 202 | end if; |
| 203 | |
| 204 | end process; |
| 205 | |
| 206 | |
| 207 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 208 | -- RAM |
| 209 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 210 | cs_ram <= '1' when address_next(30 downto 28) = "000" else '0'; |
| 211 | ram_address(31 downto 2) <= ZERO(31 downto 13) & address_next(12 downto 2); |
| 212 | |
| 213 | u2_ram: ram |
| 214 | generic map (memory_type => memory_type) |
| 215 | port map ( |
| 216 | clk => clk, |
| 217 | enable => cs_ram, |
| 218 | write_byte_enable => byte_we_next, |
| 219 | address => ram_address, |
| 220 | data_write => cpu_data_w, |
| 221 | data_read => ram_data_r); |
| 222 | |
| 223 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 224 | -- UART |
| 225 | --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 226 | |
| 227 | u3_uart: uart |
| 228 | generic map (log_file => log_file) |
| 229 | port map( |
| 230 | clk => clk, |
| 231 | reset => reset, |
| 232 | cs => cs_uart, |
| 233 | nRdWr => cpu_byte_we(0), |
| 234 | data_in => cpu_data_w(7 downto 0), |
| 235 | data_out => data_read_uart, |
| 236 | uart_read => uart_read, |
| 237 | uart_write => uart_write, |
| 238 | busy_write => uart_write_busy, |
| 239 | data_avail => uart_data_avail); |
| 240 | |
| 241 | end; --architecture logic |
| 242 | |
| 243 |
Branches:
master
