1 -------------------------------------------------------------------------- 2 -- 3 -- Copyright (C) 1993, Peter J. Ashenden 4 -- Mail: Dept. Computer Science 5 -- University of Adelaide, SA 5005, Australia 6 -- e-mail: petera@cs.adelaide.edu.au 7 -- 8 -- This program is free software; you can redistribute it and/or modify 9 -- it under the terms of the GNU General Public License as published by 10 -- the Free Software Foundation; either version 1, or (at your option) 11 -- any later version. 12 -- 13 -- This program is distributed in the hope that it will be useful, 14 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 15 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 -- GNU General Public License for more details. 17 -- 18 -- You should have received a copy of the GNU General Public License 19 -- along with this program; if not, write to the Free Software 20 -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 -- 22 -------------------------------------------------------------------------- 23 -- 24 -- $RCSfile: dlx-instrumented.vhdl,v $ $Revision: 1.1 $ $Date: 2000/05/08 14:36:48 $ 25 -- 26 -------------------------------------------------------------------------- 27 -- 28 -- Instrumented behavioural architecture for DLX, that generates 29 -- a files of instruction execution frequencies for a program. 30 -- 31 32 33 use work.dlx_instr.all, 34 work.bv_arithmetic.all, 35 std.textio.all; 36 37 38 architecture instrumented of dlx is 39 40 begin -- instrumented 41 42 interpreter: process 43 44 type reg_array is array (reg_index) of dlx_word; 45 46 variable reg : reg_array; 47 variable fp_reg : reg_array; 48 49 variable PC : dlx_word; 50 variable user_mode : boolean; 51 variable overflow, div_by_zero : boolean; 52 53 constant PC_incr : dlx_word := X"0000_0004"; 54 55 variable IR : dlx_word; 56 alias IR_opcode : dlx_opcode is IR(0 to 5); 57 alias IR_sp_func : dlx_sp_func is IR(26 to 31); 58 alias IR_fp_func : dlx_fp_func is IR(27 to 31); 59 alias IR_rs1 : dlx_reg_addr is IR(6 to 10); 60 alias IR_rs2 : dlx_reg_addr is IR(11 to 15); 61 alias IR_Itype_rd : dlx_reg_addr is IR(11 to 15); 62 alias IR_Rtype_rd : dlx_reg_addr is IR(16 to 20); 63 alias IR_immed16 : dlx_immed16 is IR(16 to 31); 64 alias IR_immed26 : dlx_immed26 is IR(6 to 31); 65 66 variable IR_opcode_num : dlx_opcode_num; 67 variable IR_sp_func_num : dlx_sp_func_num; 68 variable IR_fp_func_num : dlx_fp_func_num; 69 variable rs1, rs2, Itype_rd, Rtype_rd : reg_index; 70 variable mem_addr : dlx_address; 71 variable mem_data : dlx_word; 72 73 subtype ls_2_addr_bits is bit_vector(1 downto 0); 74 75 file data : text is out "dlx_instruction_counts"; 76 77 variable L : line; 78 79 80 --------------------------------------------------------------------------- 81 -- instrumentation: array of counters, one per instruction 82 --------------------------------------------------------------------------- 83 84 type opcode_count_array is array (dlx_opcode_num) of natural; 85 type sp_func_count_array is array (dlx_sp_func_num) of natural; 86 type fp_func_count_array is array (dlx_fp_func_num) of natural; 87 88 variable op_count : opcode_count_array := (others => 0); 89 variable sp_func_count : sp_func_count_array := (others => 0); 90 variable fp_func_count : fp_func_count_array := (others => 0); 91 92 variable instr_count : natural := 0; 93 94 --------------------------------------------------------------------------- 95 -- instrumentation: procedure to dump counter values 96 --------------------------------------------------------------------------- 97 98 procedure instrumentation_dump is 99 variable L : line; 100 begin 101 for op in dlx_opcode_num loop 102 write(L, opcode_names(op)); 103 write(L, ' '); 104 write(L, op_count(op)); 105 writeline(data, L); 106 end loop; 107 for sp_func in dlx_sp_func_num loop 108 write(L, sp_func_names(sp_func)); 109 write(L, ' '); 110 write(L, sp_func_count(sp_func)); 111 writeline(data, L); 112 end loop; 113 for fp_func in dlx_fp_func_num loop 114 write(L, fp_func_names(fp_func)); 115 write(L, ' '); 116 write(L, fp_func_count(fp_func)); 117 writeline(data, L); 118 end loop; 119 end instrumentation_dump; 120 121 --------------------------------------------------------------------------- 122 123 124 procedure write (address : in dlx_address; 125 data_width : in mem_width; 126 data : in dlx_word; 127 signal phi1, phi2 : in bit; -- 2-phase non-overlapping clks 128 signal reset : in bit; -- synchronous reset input 129 signal a : out dlx_address; -- address bus output 130 signal d : inout dlx_word_bus; -- bidirectional data bus 131 signal width : out mem_width; -- byte/halfword/word 132 signal write_enable : out bit; -- selects read/write cycle 133 signal mem_enable : out bit; -- starts memory cycle 134 signal ifetch : out bit; -- indicates instruction fetch 135 signal ready : in bit; -- status from memory system 136 Tpd_clk_out : in time -- clock to output delay 137 ) is 138 139 begin 140 wait until phi1 = '1'; 141 if reset = '1' then 142 return; 143 end if; 144 a <= address after Tpd_clk_out; 145 width <= data_width after Tpd_clk_out; 146 d <= data after Tpd_clk_out; 147 write_enable <= '1' after Tpd_clk_out; 148 mem_enable <= '1' after Tpd_clk_out; 149 ifetch <= '0' after Tpd_clk_out; 150 loop 151 wait until phi2 = '0'; 152 exit when ready = '1' or reset = '1'; 153 end loop; 154 d <= null after Tpd_clk_out; 155 write_enable <= '0' after Tpd_clk_out; 156 mem_enable <= '0' after Tpd_clk_out; 157 end write; 158 159 160 procedure bus_read (address : in dlx_address; 161 data_width : in mem_width; 162 instr_fetch : in boolean; 163 data : out dlx_word; 164 signal phi1, phi2 : in bit; -- 2-phase non-overlapping clks 165 signal reset : in bit; -- synchronous reset input 166 signal a : out dlx_address; -- address bus output 167 signal d : inout dlx_word_bus; -- bidirectional data bus 168 signal width : out mem_width; -- byte/halfword/word 169 signal write_enable : out bit; -- selects read/write cycle 170 signal mem_enable : out bit; -- starts memory cycle 171 signal ifetch : out bit; -- indicates instruction eftch 172 signal ready : in bit; -- status from memory system 173 Tpd_clk_out : in time -- clock to output delay 174 ) is 175 176 begin 177 wait until phi1 = '1'; 178 if reset = '1' then 179 return; 180 end if; 181 a <= address after Tpd_clk_out; 182 width <= data_width after Tpd_clk_out; 183 mem_enable <= '1' after Tpd_clk_out; 184 ifetch <= bit'val(boolean'pos(instr_fetch)) after Tpd_clk_out; 185 loop 186 wait until phi2 = '0'; 187 exit when ready = '1' or reset = '1'; 188 end loop; 189 data := d; 190 mem_enable <= '0' after Tpd_clk_out; 191 end bus_read; 192 193 194 begin -- interpreter 195 -- 196 -- reset the processor 197 -- 198 d <= null; 199 halt <= '0'; 200 write_enable <= '0'; 201 mem_enable <= '0'; 202 reg(0) := X"0000_0000"; 203 PC := X"0000_0000"; 204 user_mode := false; 205 -- 206 -- fetch-decode-execute loop 207 -- 208 loop 209 -- 210 -- fetch next instruction 211 -- 212 if debug then 213 write(L, tag); 214 write(L, string'(": fetching instruction...")); 215 writeline(output, L); 216 end if; 217 -- 218 bus_read(PC, width_word, true, IR, 219 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 220 Tpd_clk_out); 221 exit when reset = '1'; 222 -- 223 -- increment the PC to point to the following instruction 224 -- 225 if debug then 226 write(L, tag); 227 write(L, string'(": incrementing PC...")); 228 writeline(output, L); 229 end if; 230 -- 231 bv_add(PC, PC_incr, PC, overflow); 232 -- 233 -- decode the instruction 234 -- 235 if debug then 236 write(L, tag); 237 write(L, string'(": decoding instruction...")); 238 writeline(output, L); 239 end if; 240 -- 241 IR_opcode_num := bv_to_natural(IR_opcode); 242 IR_sp_func_num := bv_to_natural(IR_sp_func); 243 IR_fp_func_num := bv_to_natural(IR_fp_func); 244 rs1 := bv_to_natural(IR_rs1); 245 rs2 := bv_to_natural(IR_rs2); 246 Itype_rd := bv_to_natural(IR_Itype_rd); 247 Rtype_rd := bv_to_natural(IR_Rtype_rd); 248 -- 249 ------------------------------------------------------------------------- 250 -- instrumentation: increment counter for decoded instruction 251 ------------------------------------------------------------------------- 252 -- 253 op_count(IR_opcode_num) := op_count(IR_opcode_num) + 1; 254 if IR_opcode = op_special then 255 sp_func_count(IR_sp_func_num) := sp_func_count(IR_sp_func_num) + 1; 256 elsif IR_opcode = op_fparith then 257 fp_func_count(IR_fp_func_num) := fp_func_count(IR_fp_func_num) + 1; 258 end if; 259 instr_count := instr_count + 1; 260 -- 261 ------------------------------------------------------------------------- 262 -- 263 -- exectute 264 -- 265 if debug then 266 write(L, tag); 267 write(L, string'(": executing instruction...")); 268 writeline(output, L); 269 end if; 270 -- 271 case IR_opcode is 272 when op_special => 273 case IR_sp_func is 274 WHEN sp_func_nop => 275 null; 276 when sp_func_sll => 277 reg(Rtype_rd) := bv_sll(reg(rs1), bv_to_natural(reg(rs2)(27 to 31))); 278 when sp_func_srl => 279 reg(Rtype_rd) := bv_srl(reg(rs1), bv_to_natural(reg(rs2)(27 to 31))); 280 when sp_func_sra => 281 reg(Rtype_rd) := bv_sra(reg(rs1), bv_to_natural(reg(rs2)(27 to 31))); 282 when sp_func_sequ => 283 if reg(rs1) = reg(rs2) then 284 reg(Rtype_rd) := X"0000_0001"; 285 else 286 reg(Rtype_rd) := X"0000_0000"; 287 end if; 288 when sp_func_sneu => 289 if reg(rs1) /= reg(rs2) then 290 reg(Rtype_rd) := X"0000_0001"; 291 else 292 reg(Rtype_rd) := X"0000_0000"; 293 end if; 294 when sp_func_sltu => 295 if reg(rs1) < reg(rs2) then 296 reg(Rtype_rd) := X"0000_0001"; 297 else 298 reg(Rtype_rd) := X"0000_0000"; 299 end if; 300 when sp_func_sgtu => 301 if reg(rs1) > reg(rs2) then 302 reg(Rtype_rd) := X"0000_0001"; 303 else 304 reg(Rtype_rd) := X"0000_0000"; 305 end if; 306 when sp_func_sleu => 307 if reg(rs1) <= reg(rs2) then 308 reg(Rtype_rd) := X"0000_0001"; 309 else 310 reg(Rtype_rd) := X"0000_0000"; 311 end if; 312 when sp_func_sgeu => 313 if reg(rs1) >= reg(rs2) then 314 reg(Rtype_rd) := X"0000_0001"; 315 else 316 reg(Rtype_rd) := X"0000_0000"; 317 end if; 318 when sp_func_add => 319 bv_add(reg(rs1), reg(rs2), reg(Rtype_rd), overflow); 320 when sp_func_addu => 321 bv_addu(reg(rs1), reg(rs2), reg(Rtype_rd), overflow); 322 when sp_func_sub => 323 bv_sub(reg(rs1), reg(rs2), reg(Rtype_rd), overflow); 324 when sp_func_subu => 325 bv_subu(reg(rs1), reg(rs2), reg(Rtype_rd), overflow); 326 when sp_func_and => 327 reg(Rtype_rd) := reg(rs1) and reg(rs2); 328 when sp_func_or => 329 reg(Rtype_rd) := reg(rs1) or reg(rs2); 330 when sp_func_xor => 331 reg(Rtype_rd) := reg(rs1) xor reg(rs2); 332 when sp_func_seq => 333 if reg(rs1) = reg(rs2) then 334 reg(Rtype_rd) := X"0000_0001"; 335 else 336 reg(Rtype_rd) := X"0000_0000"; 337 end if; 338 when sp_func_sne => 339 if reg(rs1) /= reg(rs2) then 340 reg(Rtype_rd) := X"0000_0001"; 341 else 342 reg(Rtype_rd) := X"0000_0000"; 343 end if; 344 when sp_func_slt => 345 if bv_lt(reg(rs1), reg(rs2)) then 346 reg(Rtype_rd) := X"0000_0001"; 347 else 348 reg(Rtype_rd) := X"0000_0000"; 349 end if; 350 when sp_func_sgt => 351 if bv_gt(reg(rs1), reg(rs2)) then 352 reg(Rtype_rd) := X"0000_0001"; 353 else 354 reg(Rtype_rd) := X"0000_0000"; 355 end if; 356 when sp_func_sle => 357 if bv_le(reg(rs1), reg(rs2)) then 358 reg(Rtype_rd) := X"0000_0001"; 359 else 360 reg(Rtype_rd) := X"0000_0000"; 361 end if; 362 when sp_func_sge => 363 if bv_ge(reg(rs1), reg(rs2)) then 364 reg(Rtype_rd) := X"0000_0001"; 365 else 366 reg(Rtype_rd) := X"0000_0000"; 367 end if; 368 when sp_func_movi2s => 369 assert false 370 report "MOVI2S instruction not implemented" severity warning; 371 when sp_func_movs2i => 372 assert false 373 report "MOVS2I instruction not implemented" severity warning; 374 when sp_func_movf => 375 assert false 376 report "MOVF instruction not implemented" severity warning; 377 when sp_func_movd => 378 assert false 379 report "MOVD instruction not implemented" severity warning; 380 when sp_func_movfp2i => 381 reg(Rtype_rd) := fp_reg(rs1); 382 when sp_func_movi2fp => 383 fp_reg(Rtype_rd) := reg(rs1); 384 when others => 385 assert false 386 report "undefined special instruction function" severity error; 387 end case; 388 when op_fparith => 389 case IR_fp_func is 390 when fp_func_mult => 391 bv_mult(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), overflow); 392 when fp_func_multu => 393 bv_multu(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), overflow); 394 when fp_func_div => 395 bv_div(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), div_by_zero, overflow); 396 when fp_func_divu => 397 bv_divu(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), div_by_zero); 398 when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf | 399 fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd | 400 fp_func_cvtf2d | fp_func_cvtf2i | fp_func_cvtd2f | 401 fp_func_cvtd2i | fp_func_cvti2f | fp_func_cvti2d | 402 fp_func_eqf | fp_func_nef | fp_func_ltf | fp_func_gtf | 403 fp_func_lef | fp_func_gef | fp_func_eqd | fp_func_ned | 404 fp_func_ltd | fp_func_gtd | fp_func_led | fp_func_ged => 405 assert false 406 report "floating point instructions not implemented" severity warning; 407 when others => 408 assert false 409 report "undefined floating point instruction function" severity error; 410 end case; 411 when op_j => 412 bv_add(PC, bv_sext(IR_immed26, 32), PC, overflow); 413 when op_jal => 414 reg(link_reg) := PC; 415 bv_add(PC, bv_sext(IR_immed26, 32), PC, overflow); 416 when op_beqz => 417 if reg(rs1) = X"0000_0000" then 418 bv_add(PC, bv_sext(IR_immed16, 32), PC, overflow); 419 end if; 420 when op_bnez => 421 if reg(rs1) /= X"0000_0000" then 422 bv_add(PC, bv_sext(IR_immed16, 32), PC, overflow); 423 end if; 424 when op_bfpt => 425 assert false 426 report "BFPT instruction not implemented" severity warning; 427 when op_bfpf => 428 assert false 429 report "BFPF instruction not implemented" severity warning; 430 when op_addi => 431 bv_add(reg(rs1), bv_sext(IR_immed16, 32), reg(Itype_rd), overflow); 432 when op_addui => 433 bv_addu(reg(rs1), bv_zext(IR_immed16, 32), reg(Itype_rd), overflow); 434 when op_subi => 435 bv_sub(reg(rs1), bv_sext(IR_immed16, 32), reg(Itype_rd), overflow); 436 when op_subui => 437 bv_subu(reg(rs1), bv_zext(IR_immed16, 32), reg(Itype_rd), overflow); 438 when op_slli => 439 reg(Itype_rd) := bv_sll(reg(rs1), bv_to_natural(IR_immed16(11 to 15))); 440 when op_srli => 441 reg(Itype_rd) := bv_srl(reg(rs1), bv_to_natural(IR_immed16(11 to 15))); 442 when op_srai => 443 reg(Itype_rd) := bv_sra(reg(rs1), bv_to_natural(IR_immed16(11 to 15))); 444 when op_andi => 445 reg(Itype_rd) := reg(rs1) and bv_zext(IR_immed16, 32); 446 when op_ori => 447 reg(Itype_rd) := reg(rs1) or bv_zext(IR_immed16, 32); 448 when op_xori => 449 reg(Itype_rd) := reg(rs1) xor bv_zext(IR_immed16, 32); 450 when op_lhi => 451 reg(Itype_rd) := IR_immed16 & X"0000"; 452 when op_rfe => 453 assert false 454 report "RFE instruction not implemented" severity warning; 455 when op_trap => 456 assert false 457 report "TRAP instruction encountered, execution halted" 458 severity note; 459 halt <= '1' after Tpd_clk_out; 460 --------------------------------------------------------------------- 461 -- instrumentation: dump counters 462 --------------------------------------------------------------------- 463 instrumentation_dump; 464 --------------------------------------------------------------------- 465 wait until reset = '1'; 466 exit; 467 when op_jr => 468 PC := reg(rs1); 469 when op_jalr => 470 reg(link_reg) := PC; 471 PC := reg(rs1); 472 when op_seqi => 473 if reg(rs1) = bv_sext(IR_immed16, 32) then 474 reg(Itype_rd) := X"0000_0001"; 475 else 476 reg(Itype_rd) := X"0000_0000"; 477 end if; 478 when op_snei => 479 if reg(rs1) /= bv_sext(IR_immed16, 32) then 480 reg(Itype_rd) := X"0000_0001"; 481 else 482 reg(Itype_rd) := X"0000_0000"; 483 end if; 484 when op_slti => 485 if bv_lt(reg(rs1), bv_sext(IR_immed16, 32)) then 486 reg(Itype_rd) := X"0000_0001"; 487 else 488 reg(Itype_rd) := X"0000_0000"; 489 end if; 490 when op_sgti => 491 if bv_gt(reg(rs1), bv_sext(IR_immed16, 32)) then 492 reg(Itype_rd) := X"0000_0001"; 493 else 494 reg(Itype_rd) := X"0000_0000"; 495 end if; 496 when op_slei => 497 if bv_le(reg(rs1), bv_sext(IR_immed16, 32)) then 498 reg(Itype_rd) := X"0000_0001"; 499 else 500 reg(Itype_rd) := X"0000_0000"; 501 end if; 502 when op_sgei => 503 if bv_ge(reg(rs1), bv_sext(IR_immed16, 32)) then 504 reg(Itype_rd) := X"0000_0001"; 505 else 506 reg(Itype_rd) := X"0000_0000"; 507 end if; 508 when op_lb => 509 bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow); 510 bus_read(mem_addr, width_byte, false, mem_data, 511 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 512 Tpd_clk_out); 513 exit when reset = '1'; 514 case ls_2_addr_bits'(mem_addr(1 downto 0)) is 515 when B"00" => 516 reg(Itype_rd) := bv_sext(mem_data(0 to 7), 32); 517 when B"01" => 518 reg(Itype_rd) := bv_sext(mem_data(8 to 15), 32); 519 when B"10" => 520 reg(Itype_rd) := bv_sext(mem_data(16 to 23), 32); 521 when B"11" => 522 reg(Itype_rd) := bv_sext(mem_data(24 to 31), 32); 523 end case; 524 when op_lh => 525 bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow); 526 bus_read(mem_addr, width_halfword, false, mem_data, 527 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 528 Tpd_clk_out); 529 exit when reset = '1'; 530 if mem_addr(1) = '0' then 531 reg(Itype_rd) := bv_sext(mem_data(0 to 15), 32); 532 else 533 reg(Itype_rd) := bv_sext(mem_data(16 to 31), 32); 534 end if; 535 when op_lw => 536 bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow); 537 bus_read(mem_addr, width_word, false, mem_data, 538 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 539 Tpd_clk_out); 540 exit when reset = '1'; 541 reg(Itype_rd) := mem_data; 542 when op_lbu => 543 bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow); 544 bus_read(mem_addr, width_byte, false, mem_data, 545 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 546 Tpd_clk_out); 547 exit when reset = '1'; 548 case ls_2_addr_bits'(mem_addr(1 downto 0)) is 549 when B"00" => 550 reg(Itype_rd) := bv_zext(mem_data(0 to 7), 32); 551 when B"01" => 552 reg(Itype_rd) := bv_zext(mem_data(8 to 15), 32); 553 when B"10" => 554 reg(Itype_rd) := bv_zext(mem_data(16 to 23), 32); 555 when B"11" => 556 reg(Itype_rd) := bv_zext(mem_data(24 to 31), 32); 557 end case; 558 when op_lhu => 559 bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow); 560 bus_read(mem_addr, width_halfword, false, mem_data, 561 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 562 Tpd_clk_out); 563 exit when reset = '1'; 564 if mem_addr(1) = '0' then 565 reg(Itype_rd) := bv_zext(mem_data(0 to 15), 32); 566 else 567 reg(Itype_rd) := bv_zext(mem_data(16 to 31), 32); 568 end if; 569 when op_lf => 570 assert false 571 report "LF instruction not implemented" severity warning; 572 when op_ld => 573 assert false 574 report "LD instruction not implemented" severity warning; 575 when op_sb => 576 bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow); 577 mem_data := X"0000_0000"; 578 case ls_2_addr_bits'(mem_addr(1 downto 0)) is 579 when B"00" => 580 mem_data(0 to 7) := reg(Itype_rd)(0 to 7); 581 when B"01" => 582 mem_data(8 to 15) := reg(Itype_rd)(0 to 7); 583 when B"10" => 584 mem_data(16 to 23) := reg(Itype_rd)(0 to 7); 585 when B"11" => 586 mem_data(24 to 31) := reg(Itype_rd)(0 to 7); 587 end case; 588 write(mem_addr, width_halfword, mem_data, 589 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 590 Tpd_clk_out); 591 exit when reset = '1'; 592 when op_sh => 593 bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow); 594 mem_data := X"0000_0000"; 595 if mem_addr(1) = '0' then 596 mem_data(0 to 15) := reg(Itype_rd)(0 to 15); 597 else 598 mem_data(16 to 31) := reg(Itype_rd)(0 to 15); 599 end if; 600 write(mem_addr, width_halfword, mem_data, 601 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 602 Tpd_clk_out); 603 exit when reset = '1'; 604 when op_sw => 605 bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow); 606 mem_data := reg(Itype_rd); 607 write(mem_addr, width_word, mem_data, 608 phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready, 609 Tpd_clk_out); 610 exit when reset = '1'; 611 when op_sf => 612 assert false 613 report "SF instruction not implemented" severity warning; 614 when op_sd => 615 assert false 616 report "SD instruction not implemented" severity warning; 617 when op_sequi => 618 if reg(rs1) = bv_zext(IR_immed16, 32) then 619 reg(Itype_rd) := X"0000_0001"; 620 else 621 reg(Itype_rd) := X"0000_0000"; 622 end if; 623 when op_sneui => 624 if reg(rs1) /= bv_zext(IR_immed16, 32) then 625 reg(Itype_rd) := X"0000_0001"; 626 else 627 reg(Itype_rd) := X"0000_0000"; 628 end if; 629 when op_sltui => 630 if reg(rs1) < bv_zext(IR_immed16, 32) then 631 reg(Itype_rd) := X"0000_0001"; 632 else 633 reg(Itype_rd) := X"0000_0000"; 634 end if; 635 when op_sgtui => 636 if reg(rs1) > bv_zext(IR_immed16, 32) then 637 reg(Itype_rd) := X"0000_0001"; 638 else 639 reg(Itype_rd) := X"0000_0000"; 640 end if; 641 when op_sleui => 642 if reg(rs1) <= bv_zext(IR_immed16, 32) then 643 reg(Itype_rd) := X"0000_0001"; 644 else 645 reg(Itype_rd) := X"0000_0000"; 646 end if; 647 when op_sgeui => 648 if reg(rs1) >= bv_zext(IR_immed16, 32) then 649 reg(Itype_rd) := X"0000_0001"; 650 else 651 reg(Itype_rd) := X"0000_0000"; 652 end if; 653 when others => 654 assert false 655 report "undefined instruction" severity error; 656 end case; 657 -- 658 -- fix up R0 in case it was overwritten 659 -- 660 reg(0) := X"0000_0000"; 661 -- 662 if debug then 663 write(L, tag); 664 write(L, string'(": end of execution")); 665 writeline(output, L); 666 end if; 667 if instr_count mod 100 = 0 then 668 write(L, tag); 669 write(L, string'(": executed ")); 670 write(L, instr_count); 671 write(L, string'(" instructions")); 672 writeline(output, L); 673 end if; 674 -- 675 end loop; 676 -- 677 -- loop is only exited when reset active: wait until it goes inactive 678 -- 679 assert reset = '1' 680 report "reset code reached with reset = '0'" severity error; 681 wait until phi2 = '0' and reset = '0'; 682 -- 683 -- process interpreter now starts again from beginning 684 -- 685 end process interpreter; 686 687 end instrumented; 688
This page was generated using GHDL 0.14 (20040829) [Sokcho edition], a program written by Tristan Gingold