summaryrefslogtreecommitdiffstats
path: root/zpu/hdl/zealot/helpers/zpu_med1.vhdl
blob: fb19e0c5d3ae2b630e6a2e28cc641ed195413ecb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
------------------------------------------------------------------------------
----                                                                      ----
----  ZPU Medium + PHI I/O + BRAM                                         ----
----                                                                      ----
----  http://www.opencores.org/                                           ----
----                                                                      ----
----  Description:                                                        ----
----  ZPU is a 32 bits small stack cpu. This is a helper that joins the   ----
----  medium version, the PHI I/O basic layout and a program BRAM.        ----
----                                                                      ----
----  To Do:                                                              ----
----  -                                                                   ----
----                                                                      ----
----  Author:                                                             ----
----    - Salvador E. Tropea, salvador inti.gob.ar                        ----
----                                                                      ----
------------------------------------------------------------------------------
----                                                                      ----
---- Copyright (c) 2008 Salvador E. Tropea <salvador inti.gob.ar>         ----
---- Copyright (c) 2008 Instituto Nacional de Tecnología Industrial       ----
----                                                                      ----
---- Distributed under the BSD license                                    ----
----                                                                      ----
------------------------------------------------------------------------------
----                                                                      ----
---- Design unit:      ZPU_Med1(Structural) (Entity and architecture)     ----
---- File name:        zpu_med1.vhdl                                      ----
---- Note:             None                                               ----
---- Limitations:      None known                                         ----
---- Errors:           None known                                         ----
---- Library:          work                                               ----
---- Dependencies:     IEEE.std_logic_1164                                ----
----                   IEEE.numeric_std                                   ----
----                   zpu.zpupkg                                         ----
----                   work.zpu_memory                                    ----
---- Target FPGA:      Spartan 3 (XC3S1500-4-FG456)                       ----
---- Language:         VHDL                                               ----
---- Wishbone:         No                                                 ----
---- Synthesis tools:  Xilinx Release 9.2.03i - xst J.39                  ----
---- Simulation tools: GHDL [Sokcho edition] (0.2x)                       ----
---- Text editor:      SETEdit 0.5.x                                      ----
----                                                                      ----
------------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

library zpu;
use zpu.zpupkg.all;

-- RAM declaration
library work;
use work.zpu_memory.all;

entity ZPU_Med1 is
   generic(
      WORD_SIZE  : natural:=32;  -- 32 bits data path
      D_CARE_VAL : std_logic:='X'; -- Fill value
      CLK_FREQ   : positive:=50; -- 50 MHz clock
      BRATE      : positive:=9600; -- RS232 baudrate
      ADDR_W     : natural:=18;  -- 18 bits address space=256 kB, 128 kB I/O
      BRAM_W     : natural:=15); -- 15 bits RAM space=32 kB
   port(
      clk_i      : in  std_logic;  -- CPU clock
      rst_i      : in  std_logic;  -- Reset
      break_o    : out std_logic;  -- Break executed
      dbg_o      : out zpu_dbgo_t; -- Debug info
      rs232_tx_o : out std_logic;  -- UART Tx
      rs232_rx_i : in  std_logic); -- UART Rx
end entity ZPU_Med1;

architecture Structural of ZPU_Med1 is
   constant BYTE_BITS  : integer:=WORD_SIZE/16; -- # of bits in a word that addresses bytes
   constant IO_BIT     : integer:=ADDR_W-1; -- Address bit to determine this is an I/O
   constant BRDIVISOR  : positive:=CLK_FREQ*1e6/BRATE/4;

   -- I/O & memory (ZPU)
   signal mem_busy     : std_logic;
   signal mem_read     : unsigned(WORD_SIZE-1 downto 0);
   signal mem_write    : unsigned(WORD_SIZE-1 downto 0);
   signal mem_addr     : unsigned(ADDR_W-1 downto 0);
   signal mem_we       : std_logic;
   signal mem_re       : std_logic;

   -- Memory (SinglePort_RAM)
   signal ram_busy     : std_logic;
   signal ram_read     : unsigned(WORD_SIZE-1 downto 0);
   signal ram_addr     : unsigned(BRAM_W-1 downto BYTE_BITS);
   signal ram_we       : std_logic;
   signal ram_re       : std_logic;
   signal ram_ready_r  : std_logic:='0';

   -- I/O (ZPU_IO)
   signal io_busy      : std_logic;
   signal io_re        : std_logic;
   signal io_we        : std_logic;
   signal io_read      : unsigned(WORD_SIZE-1 downto 0);
   signal io_ready     : std_logic;
   signal io_reading_r : std_logic:='0';
   signal io_addr      : unsigned(2 downto 0);
begin
   memory: SinglePortRAM
      generic map(
         WORD_SIZE => WORD_SIZE, BYTE_BITS => BYTE_BITS, BRAM_W => BRAM_W)
      port map(
         clk_i => clk_i,
         we_i => ram_we, re_i => ram_re, addr_i => ram_addr,
         write_i => mem_write, read_o => ram_read, busy_o => ram_busy);
   ram_addr <= mem_addr(BRAM_W-1 downto BYTE_BITS);
   ram_we   <= mem_we and not(mem_addr(IO_BIT));
   ram_re   <= mem_re and not(mem_addr(IO_BIT));

   -- I/O: Phi layout
   io_map: ZPUPhiIO
      generic map(
         BRDIVISOR => BRDIVISOR, LOG_FILE => "zpu_med1_io.log")
      port map(
         clk_i => clk_i, reset_i => rst_i, busy_o => io_busy, we_i => io_we,
         re_i => io_re, data_i => mem_write, data_o => io_read,
         addr_i => io_addr, rs232_rx_i => rs232_rx_i, rs232_tx_o => rs232_tx_o,
         br_clk_i => '1');
   io_addr  <= mem_addr(4 downto 2);
   -- Here we decode 0x8xxxx as I/O and not just 0x80A00xx
   -- Note: We define the address space as 256 kB, so writing to 0x80A00xx
   -- will be as wrting to 0x200xx and hence we decode it as I/O space.
   io_we    <= mem_we and mem_addr(IO_BIT);
   io_re    <= mem_re and mem_addr(IO_BIT);
   io_ready <= (io_reading_r or io_re) and not io_busy;

   zpu : ZPUMediumCore
      generic map(
         WORD_SIZE => WORD_SIZE, ADDR_W => ADDR_W, MEM_W => BRAM_W,
         D_CARE_VAL => D_CARE_VAL)
      port map(
         clk_i => clk_i, reset_i => rst_i, enable_i => '1',
         break_o => break_o, dbg_o => dbg_o,
         -- Memory
         mem_busy_i => mem_busy, data_i => mem_read, data_o => mem_write,
         addr_o => mem_addr, write_en_o => mem_we, read_en_o => mem_re);
   mem_busy <= io_busy or ram_busy;

   -- Memory reads either come from IO or DRAM. We need to pick the right one.
   memory_control:
   process (ram_read, ram_ready_r, io_ready, io_read)
   begin
      mem_read <= (others => '0');
      if ram_ready_r='1' then
         mem_read <= ram_read;
      end if;
      if io_ready='1' then
         mem_read <= io_read;
      end if;
   end process memory_control;

   memory_control_sync:
   process (clk_i)
   begin
      if rising_edge(clk_i) then
         if rst_i='1' then
            io_reading_r <= '0';
            ram_ready_r  <= '0';
         else
            io_reading_r <= io_busy or io_re;
            ram_ready_r  <= ram_re;
         end if;
      end if;
   end process memory_control_sync;
end architecture Structural; -- Entity: ZPU_Med1

OpenPOWER on IntegriCloud