jtag: Apply Martin Strubel JTAG implementation for ZPU
[zpu.git] / zpu / hdl / zealot / devices / trace.vhdl
blobe067fe6c97847550e94a17b67e31294b2481f3ba
1 ------------------------------------------------------------------------------
2 ----                                                                      ----
3 ----  ZPU Trace Module                                                    ----
4 ----                                                                      ----
5 ----  http://www.opencores.org/                                           ----
6 ----                                                                      ----
7 ----  Description:                                                        ----
8 ----  ZPU is a 32 bits small stack cpu. This is a module to log an        ----
9 ----  execution trace.                                                    ----
10 ----                                                                      ----
11 ----  To Do:                                                              ----
12 ----  -                                                                   ----
13 ----                                                                      ----
14 ----  Author:                                                             ----
15 ----    - Øyvind Harboe, oyvind.harboe zylin.com                          ----
16 ----    - Salvador E. Tropea, salvador inti.gob.ar                        ----
17 ----                                                                      ----
18 ------------------------------------------------------------------------------
19 ----                                                                      ----
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       ----
23 ----                                                                      ----
24 ---- Distributed under the BSD license                                    ----
25 ----                                                                      ----
26 ------------------------------------------------------------------------------
27 ----                                                                      ----
28 ---- Design unit:      Trace(Behave) (Entity and architecture)            ----
29 ---- File name:        trace.vhdl                                         ----
30 ---- Note:             None                                               ----
31 ---- Limitations:      None known                                         ----
32 ---- Errors:           None known                                         ----
33 ---- Library:          zpu                                                ----
34 ---- Dependencies:     IEEE.std_logic_1164                                ----
35 ----                   IEEE.numeric_std                                   ----
36 ----                   std.textio                                         ----
37 ----                   zpu.zpupkg                                         ----
38 ----                   zpu.txt_util                                       ----
39 ---- Target FPGA:      N/A                                                ----
40 ---- Language:         VHDL                                               ----
41 ---- Wishbone:         No                                                 ----
42 ---- Synthesis tools:  N/A                                                ----
43 ---- Simulation tools: GHDL [Sokcho edition] (0.2x)                       ----
44 ---- Text editor:      SETEdit 0.5.x                                      ----
45 ----                                                                      ----
46 ------------------------------------------------------------------------------
48 library IEEE;
49 use IEEE.std_logic_1164.all;
50 use IEEE.numeric_std.all;
52 use std.textio.all;
54 library zpu;
55 use zpu.zpupkg.all;
56 use zpu.txt_util.all;
58 entity Trace is
59    generic(
60       LOG_FILE   : string:="trace.txt"; -- Name of the trace file
61       ADDR_W     : integer:=16;  -- Address width
62       WORD_SIZE  : integer:=32); -- 16/32
63    port(
64       clk_i      : in std_logic;
65       dbg_i      : in zpu_dbgo_t;
66       emu_i      : in std_logic; -- Emulation trigger
67       stop_i     : in std_logic;
68       busy_i     : in std_logic
69       );
70 end entity Trace;
71    
72 architecture Behave of Trace is
73    file l_file : text open write_mode is LOG_FILE;
74    signal counter : unsigned(63 downto 0);
75 begin
76    -- write data and control information to a file
77    receive_data:
78    process
79       variable l       : line;
80       variable l0      : line;
81       variable stk_min : unsigned(31 downto 0):=(others => '1');
82       variable stk_ini : unsigned(31 downto 0);
83       variable first   : boolean:=true;
84       variable sp_off  : unsigned(4 downto 0);
85       variable idim    : boolean:=false;
86       variable im_val  : unsigned(31 downto 0):=(others => '0');
87    begin
88       counter <= to_unsigned(1,64);
89       -- print header for the logfile
90       print(l_file,"#PC      Opcode    SP       A=[SP]    B=[SP+1]  Clk Counter        Assembler");
91       print(l_file,"#---------------------------------------------------------------------------");
92       print(l_file," ");
93    
94       wait until clk_i='1';
95       wait until clk_i='0';
96    
97       while true loop
98          counter <= counter+1;
99          if dbg_i.b_inst='1' then
100             write(l, "0x"&hstr(dbg_i.pc(ADDR_W-1 downto 0))&
101                     " 0x"&hstr(dbg_i.opcode)&
102                     " 0x"&hstr(dbg_i.sp)&
103                     " 0x"&hstr(dbg_i.stk_a)&
104                     " 0x"&hstr(dbg_i.stk_b)&
105                     " 0x"&hstr(counter)&" ");
106             --------------------------
107             -- Instruction Decoder  --
108             --------------------------
109             sp_off(4):=not dbg_i.opcode(4);
110             sp_off(3 downto 0):=dbg_i.opcode(3 downto 0);
111             if dbg_i.opcode(7 downto 7)=OPCODE_IM then
112                if idim then
113                   im_val(31 downto 7):=im_val(24 downto 0);
114                   im_val(6 downto 0):=dbg_i.opcode(6 downto 0);
115                else
116                   im_val:=unsigned(resize(signed(dbg_i.opcode(6 downto 0)),32));
117                end if;
118                idim:=true;
119                write(l,"im 0x"&hstr(dbg_i.opcode(6 downto 0))&" ; 0x"&hstr(im_val));
120             elsif dbg_i.opcode(7 downto 5)=OPCODE_STORESP then
121                if sp_off=0 then
122                   write(l,string'("storesp 0 ; pop"));
123                elsif sp_off=1 then
124                   write(l,string'("storesp 4 ; 1*4 = popdown"));
125                else
126                   write(l,"storesp "&integer'image(to_integer(sp_off)*4)&" ; "&
127                         integer'image(to_integer(sp_off))&"*4");
128                end if;
129             elsif dbg_i.opcode(7 downto 5)=OPCODE_LOADSP then
130                if sp_off=0 then
131                   write(l,string'("loadsp 0 ; dup"));
132                elsif sp_off=1 then
133                   write(l,string'("loadsp 4 ; 1*4 = dupstkb"));
134                else
135                   write(l,"loadsp "&integer'image(to_integer(sp_off)*4)&" ; "&
136                         integer'image(to_integer(sp_off))&"*4");
137                end if;
138             elsif dbg_i.opcode(7 downto 5)=OPCODE_EMULATE then
139                if dbg_i.opcode(5 downto 0)=OPCODE_EQ then
140                   write(l,string'("eq"));
141                elsif dbg_i.opcode(5 downto 0)=OPCODE_LOADB then
142                   write(l,string'("loadb"));
143                elsif dbg_i.opcode(5 downto 0)=OPCODE_NEQBRANCH then
144                   write(l,string'("neqbranch"));
145                elsif dbg_i.opcode(5 downto 0)=OPCODE_PUSHSPADD then
146                   write(l,string'("pushspadd"));
147                elsif dbg_i.opcode(5 downto 0)=OPCODE_LESSTHAN then
148                   write(l,string'("lessthan"));
149                elsif dbg_i.opcode(5 downto 0)=OPCODE_ULESSTHAN then
150                   write(l,string'("ulessthan"));
151                elsif dbg_i.opcode(5 downto 0)=OPCODE_MULT then
152                   write(l,string'("mult"));
153                elsif dbg_i.opcode(5 downto 0)=OPCODE_STOREB then
154                   write(l,string'("storeb"));
155                elsif dbg_i.opcode(5 downto 0)=OPCODE_CALLPCREL then
156                   write(l,string'("callpcrel"));
157                elsif dbg_i.opcode(5 downto 0)=OPCODE_SUB then
158                   write(l,string'("sub"));
159                elsif dbg_i.opcode(5 downto 0)=OPCODE_LESSTHANOREQUAL then
160                   write(l,string'("lessthanorequal"));
161                elsif dbg_i.opcode(5 downto 0)=OPCODE_ULESSTHANOREQUAL then
162                   write(l,string'("ulessthanorequal"));
163                elsif dbg_i.opcode(5 downto 0)=OPCODE_CALL then
164                   write(l,string'("call"));
165                elsif dbg_i.opcode(5 downto 0)=OPCODE_POPPCREL then
166                   write(l,string'("poppcrel"));
167                elsif dbg_i.opcode(5 downto 0)=OPCODE_LSHIFTRIGHT then
168                   write(l,string'("lshiftright"));
169                elsif dbg_i.opcode(5 downto 0)=OPCODE_LOADH then
170                   write(l,string'("loadh"));
171                elsif dbg_i.opcode(5 downto 0)=OPCODE_STOREH then
172                   write(l,string'("storeh"));
173                elsif dbg_i.opcode(5 downto 0)=OPCODE_ASHIFTLEFT then
174                   write(l,string'("ashiftleft"));
175                elsif dbg_i.opcode(5 downto 0)=OPCODE_ASHIFTRIGHT then
176                   write(l,string'("ashiftright"));
177                elsif dbg_i.opcode(5 downto 0)=OPCODE_NEQ then
178                   write(l,string'("neq"));
179                elsif dbg_i.opcode(5 downto 0)=OPCODE_NEG then
180                   write(l,string'("neg"));
181                elsif dbg_i.opcode(5 downto 0)=OPCODE_XOR then
182                   write(l,string'("xor"));
183                elsif dbg_i.opcode(5 downto 0)=OPCODE_DIV then
184                   write(l,string'("div"));
185                elsif dbg_i.opcode(5 downto 0)=OPCODE_MOD then
186                   write(l,string'("mod"));
187                elsif dbg_i.opcode(5 downto 0)=OPCODE_EQBRANCH then
188                   write(l,string'("eqbranch"));
189                elsif dbg_i.opcode(5 downto 0)=OPCODE_CONFIG then
190                   write(l,string'("config"));
191                elsif dbg_i.opcode(5 downto 0)=OPCODE_PUSHPC then
192                   write(l,string'("pushpc"));
193                else
194                   write(l,integer'image(to_integer(dbg_i.opcode(5 downto 0)))&
195                         " ; invalid emulated instruction");
196                end if;
197             elsif dbg_i.opcode(7 downto 4)=OPCODE_ADDSP then
198                if sp_off=0 then
199                   write(l,string'("addsp 0 ; shift"));
200                elsif sp_off=1 then
201                   write(l,string'("addsp 4 ; 1*4 = addtop"));
202                else
203                   write(l,"addsp "&integer'image(to_integer(sp_off)*4)&" ; "&
204                         integer'image(to_integer(sp_off))&"*4");
205                end if;
206             else -- OPCODE_SHORT
207                case dbg_i.opcode(3 downto 0) is
208                     when OPCODE_BREAK =>
209                          write(l,string'("break/rte"));
210                     when OPCODE_PUSHSP =>
211                          write(l,string'("pushsp"));
212                     when OPCODE_POPPC =>
213                          write(l,string'("poppc"));
214                     when OPCODE_ADD =>
215                          write(l,string'("add"));
216                     when OPCODE_OR =>
217                          write(l,string'("or"));
218                     when OPCODE_AND =>
219                          write(l,string'("and"));
220                     when OPCODE_LOAD =>
221                          write(l,string'("load"));
222                     when OPCODE_NOT =>
223                          write(l,string'("not"));
224                     when OPCODE_FLIP =>
225                          write(l,string'("flip"));
226                     when OPCODE_STORE =>
227                          write(l,string'("store"));
228                     when OPCODE_POPSP =>
229                          write(l,string'("popsp"));
230                     when OPCODE_NOP =>
231                          write(l,string'("nop"));
232                     when others =>
233                          write(l,integer'image(to_integer(dbg_i.opcode))&
234                                " ; invalid instruction");
235                end case;
236             end if;
237             if dbg_i.opcode(7 downto 7)/=OPCODE_IM then
238                idim:=false;
239             end if;
240             -----------------------------
241             -- End Instruction Decoder --
242             -----------------------------
243             writeline(l_file,l);
244             if dbg_i.sp<stk_min then
245                stk_min:=dbg_i.sp;
246             end if;
247             if first then
248                stk_ini:=dbg_i.sp+8;
249                first:=false;
250             end if;
251          end if;
252          wait until clk_i='0' or stop_i='1' or emu_i'event;
253          if emu_i'event then
254             if emu_i = '1' then
255                write(l0, "-- Enable Emulation --");
256                writeline(l_file,l0);
257                print(output,"Enter Emulation at PC 0x"&hstr(dbg_i.pc(ADDR_W-1 downto 0)));
258             else
259                write(l0, "-- Disable Emulation --");
260                writeline(l_file,l0);
261                print(output,"Leave Emulation at PC 0x"&hstr(dbg_i.pc(ADDR_W-1 downto 0)));
262             end if;
263             wait until clk_i='0';
264          end if;
265          if stop_i='1' then
266             print(output,"Minimum SP: 0x"&hstr(stk_min)&" Size: 0x"&hstr(stk_ini-stk_min));
267             wait;
268          end if;
269       end loop;
270    end process receive_data;
271 end Behave;