1 ------------------------------------------------------------------------------
5 ---- http://www.opencores.org/ ----
8 ---- ZPU is a 32 bits small stack cpu. This is the small size version. ----
9 ---- It doesn't support external memories, needs a dual ported memory. ----
15 ---- - Øyvind Harboe, oyvind.harboe zylin.com ----
16 ---- - Salvador E. Tropea, salvador inti.gob.ar ----
18 ------------------------------------------------------------------------------
20 ---- Copyright (c) 2008 Øyvind Harboe <oyvind.harboe zylin.com> ----
21 ---- Copyright (c) 2008 Salvador E. Tropea <salvador inti.gob.ar> ----
22 ---- Copyright (c) 2008 Instituto Nacional de Tecnología Industrial ----
24 ---- Distributed under the BSD license ----
26 ------------------------------------------------------------------------------
28 ---- Design unit: ZPUSmallCore(Behave) (Entity and architecture) ----
29 ---- File name: zpu_small.vhdl ----
31 ---- Limitations: None known ----
32 ---- Errors: None known ----
33 ---- Library: zpu ----
34 ---- Dependencies: IEEE.std_logic_1164 ----
35 ---- IEEE.numeric_std ----
37 ---- Target FPGA: Spartan 3 (XC3S1500-4-FG456) ----
38 ---- Language: VHDL ----
39 ---- Wishbone: No ----
40 ---- Synthesis tools: Xilinx Release 9.2.03i - xst J.39 ----
41 ---- Simulation tools: GHDL [Sokcho edition] (0.2x) ----
42 ---- Text editor: SETEdit 0.5.x ----
44 ------------------------------------------------------------------------------
47 use IEEE.std_logic_1164.ALL;
48 use IEEE.numeric_std.all;
53 entity ZPUSmallCore is
55 WORD_SIZE : integer:=32; -- Data width 16/32
56 ADDR_W : integer:=16; -- Total address space width (incl. I/O)
57 MEM_W : integer:=15; -- Memory (prog+data+stack) width
58 D_CARE_VAL : std_logic:='X'); -- Value used to fill the unsused bits
60 clk_i : in std_logic; -- System Clock
61 reset_i : in std_logic; -- Synchronous Reset
62 interrupt_i : in std_logic; -- Interrupt
63 break_o : out std_logic; -- Breakpoint opcode executed
64 dbg_o : out zpu_dbgo_t; -- Debug outputs (i.e. trace log)
65 -- BRAM (text, data, bss and stack)
66 a_we_o : out std_logic; -- BRAM A port Write Enable
67 a_addr_o : out unsigned(MEM_W-1 downto WORD_SIZE/16):=(others => '0'); -- BRAM A Address
68 a_o : out unsigned(WORD_SIZE-1 downto 0):=(others => '0'); -- Data to BRAM A port
69 a_i : in unsigned(WORD_SIZE-1 downto 0); -- Data from BRAM A port
70 b_we_o : out std_logic; -- BRAM B port Write Enable
71 b_addr_o : out unsigned(MEM_W-1 downto WORD_SIZE/16):=(others => '0'); -- BRAM B Address
72 b_o : out unsigned(WORD_SIZE-1 downto 0):=(others => '0'); -- Data to BRAM B port
73 b_i : in unsigned(WORD_SIZE-1 downto 0); -- Data from BRAM B port
75 mem_busy_i : in std_logic;
76 data_i : in unsigned(WORD_SIZE-1 downto 0);
77 data_o : out unsigned(WORD_SIZE-1 downto 0);
78 addr_o : out unsigned(ADDR_W-1 downto 0);
79 write_en_o : out std_logic;
80 read_en_o : out std_logic);
81 end entity ZPUSmallCore;
83 architecture Behave of ZPUSmallCore is
84 constant MAX_ADDR_BIT : integer:=ADDR_W-2;
85 constant BYTE_BITS : integer:=WORD_SIZE/16; -- # of bits in a word that addresses bytes
86 -- Stack Pointer initial value: BRAM size-8
87 constant SP_START_1 : unsigned(ADDR_W-1 downto 0):=to_unsigned((2**MEM_W)-8,ADDR_W);
88 constant SP_START : unsigned(MAX_ADDR_BIT downto BYTE_BITS):=
89 SP_START_1(MAX_ADDR_BIT downto BYTE_BITS);
90 constant IO_BIT : integer:=ADDR_W-1; -- Address bit to determine this is an I/O
93 signal pc_r : unsigned(MAX_ADDR_BIT downto 0):=(others => '0');
95 signal sp_r : unsigned(MAX_ADDR_BIT downto BYTE_BITS):=SP_START;
96 signal idim_r : std_logic:='0';
98 -- BRAM (text, data, bss and stack)
99 -- a_r is a register for the top of the stack [SP]
100 -- Note: as this is a stack CPU this is a very important register.
101 signal a_we_r : std_logic:='0';
102 signal a_addr_r : unsigned(MAX_ADDR_BIT downto BYTE_BITS):=(others => '0');
103 signal a_r : unsigned(WORD_SIZE-1 downto 0):=(others => '0');
104 -- b_r is a register for the next value in the stack [SP+1]
105 -- We also use the B port to fetch instructions.
106 signal b_we_r : std_logic:='0';
107 signal b_addr_r : unsigned(MAX_ADDR_BIT downto BYTE_BITS):=(others => '0');
108 signal b_r : unsigned(WORD_SIZE-1 downto 0):=(others => '0');
111 type state_t is (st_fetch, st_write_io_done, st_execute, st_add, st_or,
112 st_and, st_store, st_read_io, st_write_io, st_fetch_next,
113 st_add_sp, st_decode, st_resync);
114 signal state : state_t:=st_resync;
117 type decode_t is (dec_nop, dec_im, dec_load_sp, dec_store_sp, dec_add_sp,
118 dec_emulate, dec_break, dec_push_sp, dec_pop_pc, dec_add,
119 dec_or, dec_and, dec_load, dec_not, dec_flip, dec_store,
120 dec_pop_sp, dec_interrupt);
121 signal d_opcode_r : decode_t;
122 signal d_opcode : decode_t;
124 signal opcode : unsigned(OPCODE_W-1 downto 0); -- Decoded
125 signal opcode_r : unsigned(OPCODE_W-1 downto 0); -- Registered
128 signal in_irq_r : std_logic:='0';
130 signal addr_r : unsigned(ADDR_W-1 downto 0):=(others => '0');
132 -- Dual ported memory interface
134 a_addr_o <= a_addr_r(MEM_W-1 downto BYTE_BITS);
137 b_addr_o <= b_addr_r(MEM_W-1 downto BYTE_BITS);
140 -------------------------
141 -- Instruction Decoder --
142 -------------------------
143 -- Note: We use Port B memory to fetch the opcodes.
146 variable topcode : unsigned(OPCODE_W-1 downto 0);
148 -- Select the addressed byte inside the fetched word
149 case (to_integer(pc_r(BYTE_BITS-1 downto 0))) is
151 topcode := to_01( b_i(31 downto 24));
153 topcode := to_01( b_i(23 downto 16));
155 topcode := to_01( b_i(15 downto 8));
157 topcode := to_01( b_i(7 downto 0));
161 if (topcode(7 downto 7)=OPCODE_IM) then
163 elsif (topcode(7 downto 5)=OPCODE_STORESP) then
164 d_opcode <= dec_store_sp;
165 elsif (topcode(7 downto 5)=OPCODE_LOADSP) then
166 d_opcode <= dec_load_sp;
167 elsif (topcode(7 downto 5)=OPCODE_EMULATE) then
168 d_opcode <= dec_emulate;
169 elsif (topcode(7 downto 4)=OPCODE_ADDSP) then
170 d_opcode <= dec_add_sp;
172 case topcode(3 downto 0) is
174 d_opcode <= dec_break;
175 when OPCODE_PUSHSP =>
176 d_opcode <= dec_push_sp;
178 d_opcode <= dec_pop_pc;
186 d_opcode <= dec_load;
190 d_opcode <= dec_flip;
192 d_opcode <= dec_store;
194 d_opcode <= dec_pop_sp;
195 when others => -- OPCODE_NOP and others
199 end process decode_control;
204 variable sp_offset : unsigned(4 downto 0);
206 if rising_edge(clk_i) then
214 pc_r <= (others => '0');
216 a_addr_r <= (others => '0');
217 b_addr_r <= (others => '0');
220 a_r <= (others => '0');
221 b_r <= (others => '0');
223 addr_r <= (others => '0');
227 -- This saves LUTs, by explicitly declaring that the
228 -- a_o can be left at whatever value if a_we_r is
230 a_r <= (others => D_CARE_VAL);
231 b_r <= (others => D_CARE_VAL);
232 sp_offset:=(others => D_CARE_VAL);
233 a_addr_r <= (others => D_CARE_VAL);
234 b_addr_r <= (others => D_CARE_VAL);
235 addr_r <= a_i(ADDR_W-1 downto 0);
236 d_opcode_r <= d_opcode;
238 if interrupt_i='0' then
239 in_irq_r <= '0'; -- no longer in an interrupt
246 -- b_i contains opcode word
247 -- a_i contains top of stack
250 -- Debug info (Trace)
252 dbg_o.pc <= (others => '0');
253 dbg_o.pc(MAX_ADDR_BIT downto 0) <= pc_r;
254 dbg_o.opcode <= opcode_r;
255 dbg_o.sp <= (others => '0');
256 dbg_o.sp(MAX_ADDR_BIT downto BYTE_BITS) <= sp_r;
260 -- During the next cycle we'll be reading the next opcode
261 sp_offset(4):=not opcode_r(4);
262 sp_offset(3 downto 0):=opcode_r(3 downto 0);
270 when dec_interrupt =>
271 -- Not a real instruction, but an interrupt
276 a_r <= (others => D_CARE_VAL);
277 a_r(MAX_ADDR_BIT downto 0) <= pc_r;
279 pc_r <= to_unsigned(32,MAX_ADDR_BIT+1); -- interrupt address
280 --report "ZPU jumped to interrupt!" severity note;
286 -- Push the 7 bits (extending the sign)
289 a_r <= unsigned(resize(signed(opcode_r(6 downto 0)),WORD_SIZE));
291 -- Next IMs, shift the word and put the new value in the lower
294 a_r(WORD_SIZE-1 downto 7) <= a_i(WORD_SIZE-8 downto 0);
295 a_r(6 downto 0) <= opcode_r(6 downto 0);
300 b_addr_r <= sp_r+sp_offset;
307 a_addr_r <= sp_r+sp_offset;
309 -- Push(PC+1), PC=Opcode[4:0]*32
313 a_r <= (others => D_CARE_VAL);
314 a_r(MAX_ADDR_BIT downto 0) <= pc_r+1;
316 -- The emulate address is:
318 -- 0000 00aa aaa0 0000
319 pc_r <= (others => '0');
320 pc_r(9 downto 5) <= opcode_r(4 downto 0);
322 -- Push(Pop()+[SP+Offset])
324 b_addr_r <= sp_r+sp_offset;
327 --report "Break instruction encountered" severity failure;
334 a_r <= (others => D_CARE_VAL);
335 a_r(MAX_ADDR_BIT downto BYTE_BITS) <= sp_r;
338 pc_r <= a_i(MAX_ADDR_BIT downto 0);
346 -- Push(Pop() or Pop())
350 -- Push(Pop() and Pop())
355 if a_i(IO_BIT)='1' then
356 addr_r <= a_i(ADDR_W-1 downto 0);
360 a_addr_r <= a_i(MAX_ADDR_BIT downto BYTE_BITS);
364 a_addr_r <= sp_r(MAX_ADDR_BIT downto BYTE_BITS);
369 a_addr_r <= sp_r(MAX_ADDR_BIT downto BYTE_BITS);
371 for i in 0 to WORD_SIZE-1 loop
372 a_r(i) <= a_i(WORD_SIZE-1-i);
375 -- a=Pop(), b=Pop(), [a]=b
378 if a_i(IO_BIT)='1' then
379 state <= st_write_io;
385 sp_r <= a_i(MAX_ADDR_BIT downto BYTE_BITS);
388 -- Default, keep addressing to of the stack (A)
395 -- Wait until memory I/O isn't busy
396 if mem_busy_i='0' then
405 addr_r <= a_i(ADDR_W-1 downto 0);
406 state <= st_write_io_done;
407 when st_write_io_done =>
408 -- Wait until memory I/O isn't busy
409 if mem_busy_i='0' then
413 -- We need to resync. During the *next* cycle
414 -- we'll fetch the opcode @ pc and thus it will
415 -- be available for st_execute the cycle after
417 b_addr_r <= pc_r(MAX_ADDR_BIT downto BYTE_BITS);
418 state <= st_fetch_next;
419 when st_fetch_next =>
420 -- At this point a_i contains the value that is either
421 -- from the top of stack or should be copied to the top of the stack
428 if interrupt_i='1' and in_irq_r='0' and idim_r='0' then
429 -- We got an interrupt, execute interrupt instead of next instruction
431 d_opcode_r <= dec_interrupt;
433 -- during the st_execute cycle we'll be fetching SP+1
440 a_addr_r <= a_i(MAX_ADDR_BIT downto BYTE_BITS);
466 end if; -- else reset_i/='1'
467 end if; -- rising_edge(clk_i)
468 end process opcode_control;
471 end architecture Behave; -- Entity: ZPUSmallCore