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: controller-behaviour.vhdl,v $ $Revision: 1.1 $ $Date: 2000/05/08 14:36:47 $ 25 -- 26 -------------------------------------------------------------------------- 27 -- 28 -- Behavioural architecture of DLX control section. 29 -- 30 31 32 use work.bv_arithmetic.all, std.textio.all; 33 34 architecture behaviour of controller is 35 36 begin -- behaviour 37 38 sequencer : process 39 40 alias IR_opcode : dlx_opcode is current_instruction(0 to 5); 41 alias IR_sp_func : dlx_sp_func is current_instruction(26 to 31); 42 alias IR_fp_func : dlx_fp_func is current_instruction(27 to 31); 43 alias IR_rs1 : dlx_reg_addr is current_instruction(6 to 10); 44 alias IR_rs2 : dlx_reg_addr is current_instruction(11 to 15); 45 alias IR_Itype_rd : dlx_reg_addr is current_instruction(11 to 15); 46 alias IR_Rtype_rd : dlx_reg_addr is current_instruction(16 to 20); 47 alias IR_immed16 : dlx_immed16 is current_instruction(16 to 31); 48 alias IR_immed26 : dlx_immed26 is current_instruction(6 to 31); 49 50 variable IR_opcode_num : dlx_opcode_num; 51 variable IR_sp_func_num : dlx_sp_func_num; 52 variable IR_fp_func_num : dlx_fp_func_num; 53 54 variable result_of_set_is_1, branch_taken : boolean; 55 56 variable L : line; 57 58 procedure bus_instruction_fetch is 59 begin 60 -- use PC as address 61 mem_addr_mux_sel <= '0' after Tpd_clk_ctrl; 62 -- set up memory control signals 63 width <= width_word after Tpd_clk_ctrl; 64 ifetch <= '1' after Tpd_clk_ctrl; 65 mem_enable <= '1' after Tpd_clk_ctrl; 66 -- wait until phi2, then enable IR input 67 wait until phi2 = '1'; 68 ir_latch_en <= '1' after Tpd_clk_ctrl; 69 -- wait until memory is ready at end of phi2 70 loop 71 wait until phi2 = '0'; 72 if reset = '1' then 73 return; 74 end if; 75 exit when ready = '1'; 76 end loop; 77 -- disable IR input and memory control signals 78 ir_latch_en <= '0' after Tpd_clk_ctrl; 79 mem_enable <= '0' after Tpd_clk_ctrl; 80 end bus_instruction_fetch; 81 82 procedure bus_data_read(read_width : in mem_width) is 83 begin 84 -- use MAR as address 85 mem_addr_mux_sel <= '1' after Tpd_clk_ctrl; 86 -- set up memory control signals 87 width <= read_width after Tpd_clk_ctrl; 88 ifetch <= '0' after Tpd_clk_ctrl; 89 mem_enable <= '1' after Tpd_clk_ctrl; 90 -- wait until phi2, then enable MDR input 91 wait until phi2 = '1'; 92 mdr_mux_sel <= '1' after Tpd_clk_ctrl; 93 mdr_latch_en <= '1' after Tpd_clk_ctrl; 94 -- wait until memory is ready at end of phi2 95 loop 96 wait until phi2 = '0'; 97 if reset = '1' then 98 return; 99 end if; 100 exit when ready = '1'; 101 end loop; 102 -- disable MDR input and memory control signals 103 mdr_latch_en <= '0' after Tpd_clk_ctrl; 104 mem_enable <= '0' after Tpd_clk_ctrl; 105 end bus_data_read; 106 107 procedure bus_data_write(write_width : in mem_width) is 108 begin 109 -- use MAR as address 110 mem_addr_mux_sel <= '1' after Tpd_clk_ctrl; 111 -- enable MDR output 112 mdr_out_en3 <= '1' after Tpd_clk_ctrl; 113 -- set up memory control signals 114 width <= write_width after Tpd_clk_ctrl; 115 ifetch <= '0' after Tpd_clk_ctrl; 116 write_enable <= '1' after Tpd_clk_ctrl; 117 mem_enable <= '1' after Tpd_clk_ctrl; 118 -- wait until memory is ready at end of phi2 119 loop 120 wait until phi2 = '0'; 121 if reset = '1' then 122 return; 123 end if; 124 exit when ready = '1'; 125 end loop; 126 -- disable MDR output and memory control signals 127 write_enable <= '0' after Tpd_clk_ctrl; 128 mem_enable <= '0' after Tpd_clk_ctrl; 129 mdr_out_en3 <= '0' after Tpd_clk_ctrl; 130 end bus_data_write; 131 132 procedure do_set_result is 133 begin 134 wait until phi1 = '1'; 135 if result_of_set_is_1 then 136 const2 <= X"0000_0001" after Tpd_clk_const; 137 else 138 const2 <= X"0000_0000" after Tpd_clk_const; 139 end if; 140 alu_latch_en <= '1' after Tpd_clk_ctrl; 141 alu_function <= alu_pass_s2 after Tpd_clk_ctrl; 142 -- 143 wait until phi1 = '0'; 144 alu_latch_en <= '0' after Tpd_clk_ctrl; 145 const2 <= null after Tpd_clk_const; 146 -- 147 wait until phi2 = '1'; 148 c_latch_en <= '1' after Tpd_clk_ctrl; 149 -- 150 wait until phi2 = '0'; 151 c_latch_en <= '0' after Tpd_clk_ctrl; 152 end do_set_result; 153 154 procedure do_EX_set_unsigned(immed : boolean) is 155 begin 156 wait until phi1 = '1'; 157 a_out_en <= '1' after Tpd_clk_ctrl; 158 if immed then 159 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl; 160 ir_immed_unsigned2 <= '1' after Tpd_clk_ctrl; 161 ir_immed_en2 <= '1' after Tpd_clk_ctrl; 162 else 163 b_out_en <= '1' after Tpd_clk_ctrl; 164 end if; 165 alu_latch_en <= '1' after Tpd_clk_ctrl; 166 alu_function <= alu_subu after Tpd_clk_ctrl; 167 -- 168 wait until phi1 = '0'; 169 alu_latch_en <= '0' after Tpd_clk_ctrl; 170 a_out_en <= '0' after Tpd_clk_ctrl; 171 if immed then 172 ir_immed_en2 <= '0' after Tpd_clk_ctrl; 173 else 174 b_out_en <= '0' after Tpd_clk_ctrl; 175 end if; 176 -- 177 wait until phi2 = '0'; 178 if immed then 179 case IR_opcode is 180 when op_sequi => 181 result_of_set_is_1 := alu_zero = '1'; 182 when op_sneui => 183 result_of_set_is_1 := alu_zero /= '1'; 184 when op_sltui => 185 result_of_set_is_1 := alu_overflow = '1'; 186 when op_sgtui => 187 result_of_set_is_1 := alu_overflow /= '1' and alu_zero /= '1'; 188 when op_sleui => 189 result_of_set_is_1 := alu_overflow = '1' or alu_zero = '1'; 190 when op_sgeui => 191 result_of_set_is_1 := alu_overflow /= '1'; 192 when others => 193 null; 194 end case; 195 else 196 case IR_sp_func is 197 when sp_func_sequ => 198 result_of_set_is_1 := alu_zero = '1'; 199 when sp_func_sneu => 200 result_of_set_is_1 := alu_zero /= '1'; 201 when sp_func_sltu => 202 result_of_set_is_1 := alu_overflow = '1'; 203 when sp_func_sgtu => 204 result_of_set_is_1 := alu_overflow /= '1' and alu_zero /= '1'; 205 when sp_func_sleu => 206 result_of_set_is_1 := alu_overflow = '1' or alu_zero = '1'; 207 when sp_func_sgeu => 208 result_of_set_is_1 := alu_overflow /= '1'; 209 when others => 210 null; 211 end case; 212 end if; 213 -- 214 do_set_result; 215 end do_EX_set_unsigned; 216 217 procedure do_EX_set_signed(immed : boolean) is 218 begin 219 wait until phi1 = '1'; 220 a_out_en <= '1' after Tpd_clk_ctrl; 221 if immed then 222 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl; 223 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl; 224 ir_immed_en2 <= '1' after Tpd_clk_ctrl; 225 else 226 b_out_en <= '1' after Tpd_clk_ctrl; 227 end if; 228 alu_latch_en <= '1' after Tpd_clk_ctrl; 229 alu_function <= alu_sub after Tpd_clk_ctrl; 230 -- 231 wait until phi1 = '0'; 232 alu_latch_en <= '0' after Tpd_clk_ctrl; 233 a_out_en <= '0' after Tpd_clk_ctrl; 234 if immed then 235 ir_immed_en2 <= '0' after Tpd_clk_ctrl; 236 else 237 b_out_en <= '0' after Tpd_clk_ctrl; 238 end if; 239 -- 240 wait until phi2 = '0'; 241 if immed then 242 case IR_opcode is 243 when op_seqi => 244 result_of_set_is_1 := alu_zero = '1'; 245 when op_snei => 246 result_of_set_is_1 := alu_zero /= '1'; 247 when op_slti => 248 result_of_set_is_1 := alu_negative = '1'; 249 when op_sgti => 250 result_of_set_is_1 := alu_negative /= '1' and alu_zero /= '1'; 251 when op_slei => 252 result_of_set_is_1 := alu_negative = '1' or alu_zero = '1'; 253 when op_sgei => 254 result_of_set_is_1 := alu_negative /= '1'; 255 when others => 256 null; 257 end case; 258 else 259 case IR_sp_func is 260 when sp_func_seq => 261 result_of_set_is_1 := alu_zero = '1'; 262 when sp_func_sne => 263 result_of_set_is_1 := alu_zero /= '1'; 264 when sp_func_slt => 265 result_of_set_is_1 := alu_negative = '1'; 266 when sp_func_sgt => 267 result_of_set_is_1 := alu_negative /= '1' and alu_zero /= '1'; 268 when sp_func_sle => 269 result_of_set_is_1 := alu_negative = '1' or alu_zero = '1'; 270 when sp_func_sge => 271 result_of_set_is_1 := alu_negative /= '1'; 272 when others => 273 null; 274 end case; 275 end if; 276 -- 277 do_set_result; 278 end do_EX_set_signed; 279 280 procedure do_EX_arith_logic is 281 begin 282 wait until phi1 = '1'; 283 a_out_en <= '1' after Tpd_clk_ctrl; 284 b_out_en <= '1' after Tpd_clk_ctrl; 285 alu_latch_en <= '1' after Tpd_clk_ctrl; 286 case IR_sp_func is 287 when sp_func_add => 288 alu_function <= alu_add after Tpd_clk_ctrl; 289 when sp_func_addu => 290 alu_function <= alu_addu after Tpd_clk_ctrl; 291 when sp_func_sub => 292 alu_function <= alu_sub after Tpd_clk_ctrl; 293 when sp_func_subu => 294 alu_function <= alu_subu after Tpd_clk_ctrl; 295 when sp_func_and => 296 alu_function <= alu_and after Tpd_clk_ctrl; 297 when sp_func_or => 298 alu_function <= alu_or after Tpd_clk_ctrl; 299 when sp_func_xor => 300 alu_function <= alu_xor after Tpd_clk_ctrl; 301 when sp_func_sll => 302 alu_function <= alu_sll after Tpd_clk_ctrl; 303 when sp_func_srl => 304 alu_function <= alu_srl after Tpd_clk_ctrl; 305 when sp_func_sra => 306 alu_function <= alu_sra after Tpd_clk_ctrl; 307 when others => 308 null; 309 end case; -- IR_sp_func 310 -- 311 wait until phi1 = '0'; 312 alu_latch_en <= '0' after Tpd_clk_ctrl; 313 a_out_en <= '0' after Tpd_clk_ctrl; 314 b_out_en <= '0' after Tpd_clk_ctrl; 315 -- 316 wait until phi2 = '1'; 317 c_latch_en <= '1' after Tpd_clk_ctrl; 318 -- 319 wait until phi2 = '0'; 320 c_latch_en <= '0' after Tpd_clk_ctrl; 321 end do_EX_arith_logic; 322 323 procedure do_EX_arith_logic_immed is 324 begin 325 wait until phi1 = '1'; 326 a_out_en <= '1' after Tpd_clk_ctrl; 327 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl; 328 if IR_opcode = op_addi or IR_opcode = op_subi then 329 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl; 330 else 331 ir_immed_unsigned2 <= '1' after Tpd_clk_ctrl; 332 end if; 333 ir_immed_en2 <= '1' after Tpd_clk_ctrl; 334 alu_latch_en <= '1' after Tpd_clk_ctrl; 335 case IR_opcode is 336 when op_addi => 337 alu_function <= alu_add after Tpd_clk_ctrl; 338 when op_subi => 339 alu_function <= alu_sub after Tpd_clk_ctrl; 340 when op_addui => 341 alu_function <= alu_addu after Tpd_clk_ctrl; 342 when op_subui => 343 alu_function <= alu_subu after Tpd_clk_ctrl; 344 when op_andi => 345 alu_function <= alu_and after Tpd_clk_ctrl; 346 when op_ori => 347 alu_function <= alu_or after Tpd_clk_ctrl; 348 when op_xori => 349 alu_function <= alu_xor after Tpd_clk_ctrl; 350 when op_slli => 351 alu_function <= alu_sll after Tpd_clk_ctrl; 352 when op_srli => 353 alu_function <= alu_srl after Tpd_clk_ctrl; 354 when op_srai => 355 alu_function <= alu_sra after Tpd_clk_ctrl; 356 when others => 357 null; 358 end case; -- IR_opcode 359 -- 360 wait until phi1 = '0'; 361 alu_latch_en <= '0' after Tpd_clk_ctrl; 362 a_out_en <= '0' after Tpd_clk_ctrl; 363 ir_immed_en2 <= '0' after Tpd_clk_ctrl; 364 -- 365 wait until phi2 = '1'; 366 c_latch_en <= '1' after Tpd_clk_ctrl; 367 -- 368 wait until phi2 = '0'; 369 c_latch_en <= '0' after Tpd_clk_ctrl; 370 end do_EX_arith_logic_immed; 371 372 procedure do_EX_link is 373 begin 374 wait until phi1 = '1'; 375 pc_out_en1 <= '1' after Tpd_clk_ctrl; 376 alu_latch_en <= '1' after Tpd_clk_ctrl; 377 alu_function <= alu_pass_s1 after Tpd_clk_ctrl; 378 -- 379 wait until phi1 = '0'; 380 alu_latch_en <= '0' after Tpd_clk_ctrl; 381 pc_out_en1 <= '0' after Tpd_clk_ctrl; 382 -- 383 wait until phi2 = '1'; 384 c_latch_en <= '1' after Tpd_clk_ctrl; 385 -- 386 wait until phi2 = '0'; 387 c_latch_en <= '0' after Tpd_clk_ctrl; 388 end do_EX_link; 389 390 procedure do_EX_lhi is 391 begin 392 wait until phi1 = '1'; 393 ir_immed_sel1 <= immed_size_16 after Tpd_clk_ctrl; 394 ir_immed_unsigned1 <= '1' after Tpd_clk_ctrl; 395 ir_immed_en1 <= '1' after Tpd_clk_ctrl; 396 const2 <= X"0000_0010" after Tpd_clk_const; -- shift by 16 bits 397 alu_latch_en <= '1' after Tpd_clk_ctrl; 398 alu_function <= alu_sll after Tpd_clk_ctrl; 399 -- 400 wait until phi1 = '0'; 401 alu_latch_en <= '0' after Tpd_clk_ctrl; 402 ir_immed_en1 <= '0' after Tpd_clk_ctrl; 403 const2 <= null after Tpd_clk_const; 404 -- 405 wait until phi2 = '1'; 406 c_latch_en <= '1' after Tpd_clk_ctrl; 407 -- 408 wait until phi2 = '0'; 409 c_latch_en <= '0' after Tpd_clk_ctrl; 410 end do_EX_lhi; 411 412 procedure do_EX_branch is 413 begin 414 wait until phi1 = '1'; 415 a_out_en <= '1' after Tpd_clk_ctrl; 416 const2 <= X"0000_0000" after Tpd_clk_const; 417 alu_latch_en <= '1' after Tpd_clk_ctrl; 418 alu_function <= alu_sub after Tpd_clk_ctrl; 419 -- 420 wait until phi1 = '0'; 421 alu_latch_en <= '0' after Tpd_clk_ctrl; 422 a_out_en <= '0' after Tpd_clk_ctrl; 423 const2 <= null after Tpd_clk_const; 424 -- 425 wait until phi2 = '0'; 426 if IR_opcode = op_beqz then 427 branch_taken := alu_zero = '1'; 428 else 429 branch_taken := alu_zero /= '1'; 430 end if; 431 end do_EX_branch; 432 433 procedure do_EX_load_store is 434 begin 435 wait until phi1 = '1'; 436 a_out_en <= '1' after Tpd_clk_ctrl; 437 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl; 438 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl; 439 ir_immed_en2 <= '1' after Tpd_clk_ctrl; 440 alu_function <= alu_add after Tpd_clk_ctrl; 441 alu_latch_en <= '1' after Tpd_clk_ctrl; 442 -- 443 wait until phi1 = '0'; 444 alu_latch_en <= '0' after Tpd_clk_ctrl; 445 a_out_en <= '0' after Tpd_clk_ctrl; 446 ir_immed_en2 <= '0' after Tpd_clk_ctrl; 447 -- 448 wait until phi2 = '1'; 449 mar_latch_en <= '1' after Tpd_clk_ctrl; 450 -- 451 wait until phi2 = '0'; 452 mar_latch_en <= '0' after Tpd_clk_ctrl; 453 end do_EX_load_store; 454 455 procedure do_MEM_jump is 456 begin 457 wait until phi1 = '1'; 458 pc_out_en1 <= '1' after Tpd_clk_ctrl; 459 ir_immed_sel2 <= immed_size_26 after Tpd_clk_ctrl; 460 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl; 461 ir_immed_en2 <= '1' after Tpd_clk_ctrl; 462 alu_latch_en <= '1' after Tpd_clk_ctrl; 463 alu_function <= alu_add after Tpd_clk_ctrl; 464 -- 465 wait until phi1 = '0'; 466 alu_latch_en <= '0' after Tpd_clk_ctrl; 467 pc_out_en1 <= '0' after Tpd_clk_ctrl; 468 ir_immed_en2 <= '0' after Tpd_clk_ctrl; 469 -- 470 wait until phi2 = '1'; 471 pc_latch_en <= '1' after Tpd_clk_ctrl; 472 -- 473 wait until phi2 = '0'; 474 pc_latch_en <= '0' after Tpd_clk_ctrl; 475 end do_MEM_jump; 476 477 procedure do_MEM_jump_reg is 478 begin 479 wait until phi1 = '1'; 480 a_out_en <= '1' after Tpd_clk_ctrl; 481 alu_latch_en <= '1' after Tpd_clk_ctrl; 482 alu_function <= alu_pass_s1 after Tpd_clk_ctrl; 483 -- 484 wait until phi1 = '0'; 485 alu_latch_en <= '0' after Tpd_clk_ctrl; 486 a_out_en <= '0' after Tpd_clk_ctrl; 487 -- 488 wait until phi2 = '1'; 489 pc_latch_en <= '1' after Tpd_clk_ctrl; 490 -- 491 wait until phi2 = '0'; 492 pc_latch_en <= '0' after Tpd_clk_ctrl; 493 end do_MEM_jump_reg; 494 495 procedure do_MEM_branch is 496 begin 497 wait until phi1 = '1'; 498 pc_out_en1 <= '1' after Tpd_clk_ctrl; 499 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl; 500 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl; 501 ir_immed_en2 <= '1' after Tpd_clk_ctrl; 502 alu_latch_en <= '1' after Tpd_clk_ctrl; 503 alu_function <= alu_add after Tpd_clk_ctrl; 504 -- 505 wait until phi1 = '0'; 506 alu_latch_en <= '0' after Tpd_clk_ctrl; 507 pc_out_en1 <= '0' after Tpd_clk_ctrl; 508 ir_immed_en2 <= '0' after Tpd_clk_ctrl; 509 -- 510 wait until phi2 = '1'; 511 pc_latch_en <= '1' after Tpd_clk_ctrl; 512 -- 513 wait until phi2 = '0'; 514 pc_latch_en <= '0' after Tpd_clk_ctrl; 515 end do_MEM_branch; 516 517 procedure do_MEM_load is 518 begin 519 wait until phi1 = '1'; 520 bus_data_read(width_word); 521 if reset = '1' then 522 return; 523 end if; 524 -- 525 wait until phi1 = '1'; 526 mdr_out_en1 <= '1' after Tpd_clk_ctrl; 527 alu_function <= alu_pass_s1 after Tpd_clk_ctrl; 528 alu_latch_en <= '1' after Tpd_clk_ctrl; 529 -- 530 wait until phi1 = '0'; 531 mdr_out_en1 <= '0' after Tpd_clk_ctrl; 532 alu_latch_en <= '0' after Tpd_clk_ctrl; 533 -- 534 wait until phi2 = '1'; 535 c_latch_en <= '1' after Tpd_clk_ctrl; 536 -- 537 wait until phi2 = '0'; 538 c_latch_en <= '0' after Tpd_clk_ctrl; 539 end do_MEM_load; 540 541 procedure do_MEM_store is 542 begin 543 wait until phi1 = '1'; 544 b_out_en <= '1' after Tpd_clk_ctrl; 545 alu_function <= alu_pass_s2 after Tpd_clk_ctrl; 546 alu_latch_en <= '1' after Tpd_clk_ctrl; 547 -- 548 wait until phi1 = '0'; 549 b_out_en <= '0' after Tpd_clk_ctrl; 550 alu_latch_en <= '0' after Tpd_clk_ctrl; 551 -- 552 wait until phi2 = '1'; 553 mdr_mux_sel <= '0' after Tpd_clk_ctrl; 554 mdr_latch_en <= '1' after Tpd_clk_ctrl; 555 -- 556 wait until phi2 = '0'; 557 mdr_latch_en <= '0' after Tpd_clk_ctrl; 558 -- 559 wait until phi1 = '1'; 560 bus_data_write(width_word); 561 end do_MEM_store; 562 563 procedure do_WB(Rd : dlx_reg_addr) is 564 begin 565 wait until phi1 = '1'; 566 reg_dest_addr <= Rd after Tpd_clk_ctrl; 567 reg_write <= '1' after Tpd_clk_ctrl; 568 -- 569 wait until phi2 = '0'; 570 reg_write <= '0' after Tpd_clk_ctrl; 571 end do_WB; 572 573 574 begin -- sequencer 575 -- 576 ---------------------------------------------------------------- 577 -- initialize all control signals 578 ---------------------------------------------------------------- 579 if debug then 580 write(L, string'("controller: initializing")); 581 writeline(output, L); 582 end if; 583 -- 584 halt <= '0' after Tpd_clk_ctrl; 585 width <= width_word after Tpd_clk_ctrl; 586 write_enable <= '0' after Tpd_clk_ctrl; 587 mem_enable <= '0' after Tpd_clk_ctrl; 588 ifetch <= '0' after Tpd_clk_ctrl; 589 alu_latch_en <= '0' after Tpd_clk_ctrl; 590 alu_function <= alu_add after Tpd_clk_ctrl; 591 reg_s1_addr <= B"00000" after Tpd_clk_ctrl; 592 reg_s2_addr <= B"00000" after Tpd_clk_ctrl; 593 reg_dest_addr <= B"00000" after Tpd_clk_ctrl; 594 reg_write <= '0' after Tpd_clk_ctrl; 595 c_latch_en <= '0' after Tpd_clk_ctrl; 596 a_latch_en <= '0' after Tpd_clk_ctrl; 597 a_out_en <= '0' after Tpd_clk_ctrl; 598 b_latch_en <= '0' after Tpd_clk_ctrl; 599 b_out_en <= '0' after Tpd_clk_ctrl; 600 temp_latch_en <= '0' after Tpd_clk_ctrl; 601 temp_out_en1 <= '0' after Tpd_clk_ctrl; 602 temp_out_en2 <= '0' after Tpd_clk_ctrl; 603 iar_latch_en <= '0' after Tpd_clk_ctrl; 604 iar_out_en1 <= '0' after Tpd_clk_ctrl; 605 iar_out_en2 <= '0' after Tpd_clk_ctrl; 606 pc_latch_en <= '0' after Tpd_clk_ctrl; 607 pc_out_en1 <= '0' after Tpd_clk_ctrl; 608 pc_out_en2 <= '0' after Tpd_clk_ctrl; 609 mar_latch_en <= '0' after Tpd_clk_ctrl; 610 mar_out_en1 <= '0' after Tpd_clk_ctrl; 611 mar_out_en2 <= '0' after Tpd_clk_ctrl; 612 mem_addr_mux_sel <= '0' after Tpd_clk_ctrl; 613 mdr_latch_en <= '0' after Tpd_clk_ctrl; 614 mdr_out_en1 <= '0' after Tpd_clk_ctrl; 615 mdr_out_en2 <= '0' after Tpd_clk_ctrl; 616 mdr_out_en3 <= '0' after Tpd_clk_ctrl; 617 mdr_mux_sel <= '0' after Tpd_clk_ctrl; 618 ir_latch_en <= '0' after Tpd_clk_ctrl; 619 ir_immed_sel1 <= immed_size_16 after Tpd_clk_ctrl; 620 ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl; 621 ir_immed_unsigned1 <= '0' after Tpd_clk_ctrl; 622 ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl; 623 ir_immed_en1 <= '0' after Tpd_clk_ctrl; 624 ir_immed_en2 <= '0' after Tpd_clk_ctrl; 625 const1 <= null after Tpd_clk_const; 626 const2 <= null after Tpd_clk_const; 627 -- 628 wait until phi2 = '0' and reset = '0'; 629 -- 630 ---------------------------------------------------------------- 631 -- control loop 632 ---------------------------------------------------------------- 633 loop 634 -- 635 ---------------------------------------------------------------- 636 -- fetch next instruction (IF) 637 ---------------------------------------------------------------- 638 wait until phi1 = '1'; 639 if debug then 640 write(L, string'("controller: instruction fetch")); 641 writeline(output, L); 642 end if; 643 -- 644 bus_instruction_fetch; 645 -- 646 ---------------------------------------------------------------- 647 -- instruction decode, source register read, and PC increment (ID) 648 ---------------------------------------------------------------- 649 wait until phi1 = '1'; 650 if debug then 651 write(L, string'("controller: decode, reg-read and PC incr")); 652 writeline(output, L); 653 end if; 654 -- 655 IR_opcode_num := bv_to_natural(IR_opcode); 656 IR_sp_func_num := bv_to_natural(IR_sp_func); 657 IR_fp_func_num := bv_to_natural(IR_fp_func); 658 -- 659 reg_s1_addr <= IR_rs1 after Tpd_clk_ctrl; 660 reg_s2_addr <= IR_rs2 after Tpd_clk_ctrl; 661 a_latch_en <= '1' after Tpd_clk_ctrl; 662 b_latch_en <= '1' after Tpd_clk_ctrl; 663 -- 664 pc_out_en1 <= '1' after Tpd_clk_ctrl; 665 const2 <= X"0000_0004" after Tpd_clk_const; 666 alu_latch_en <= '1' after Tpd_clk_ctrl; 667 alu_function <= alu_addu after Tpd_clk_ctrl; 668 -- 669 wait until phi1 = '0'; 670 a_latch_en <= '0' after Tpd_clk_ctrl; 671 b_latch_en <= '0' after Tpd_clk_ctrl; 672 alu_latch_en <= '0' after Tpd_clk_ctrl; 673 pc_out_en1 <= '0' after Tpd_clk_ctrl; 674 const2 <= null after Tpd_clk_const; 675 -- 676 wait until phi2 = '1'; 677 pc_latch_en <= '1' after Tpd_clk_ctrl; 678 -- 679 wait until phi2 = '0'; 680 pc_latch_en <= '0' after Tpd_clk_ctrl; 681 -- 682 ---------------------------------------------------------------- 683 -- execute instruction, (EX, MEM, WB) 684 ---------------------------------------------------------------- 685 if debug then 686 write(L, string'("controller: execute")); 687 writeline(output, L); 688 end if; 689 -- 690 case IR_opcode is 691 when op_special => 692 case IR_sp_func is 693 when sp_func_nop => 694 null; 695 when sp_func_sequ | sp_func_sneu | 696 sp_func_sltu | sp_func_sgtu | 697 sp_func_sleu | sp_func_sgeu => 698 do_EX_set_unsigned(immed => false); 699 do_WB(IR_Rtype_rd); 700 when sp_func_add | sp_func_addu | 701 sp_func_sub | sp_func_subu | 702 sp_func_and | sp_func_or | sp_func_xor | 703 sp_func_sll | sp_func_srl | sp_func_sra => 704 do_EX_arith_logic; 705 do_WB(IR_Rtype_rd); 706 when sp_func_seq | sp_func_sne | 707 sp_func_slt | sp_func_sgt | 708 sp_func_sle | sp_func_sge => 709 do_EX_set_signed(immed => false); 710 do_WB(IR_Rtype_rd); 711 when sp_func_movi2s => 712 assert false 713 report "MOVI2S instruction not implemented" severity warning; 714 when sp_func_movs2i => 715 assert false 716 report "MOVS2I instruction not implemented" severity warning; 717 when sp_func_movf => 718 assert false 719 report "MOVF instruction not implemented" severity warning; 720 when sp_func_movd => 721 assert false 722 report "MOVD instruction not implemented" severity warning; 723 when sp_func_movfp2i => 724 assert false 725 report "MOVFP2I instruction not implemented" severity warning; 726 when sp_func_movi2fp => 727 assert false 728 report "MOVI2FP instruction not implemented" severity warning; 729 when others => 730 assert false 731 report "undefined special instruction function" severity error; 732 end case; 733 when op_fparith => 734 case IR_fp_func is 735 when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf | 736 fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd | 737 fp_func_mult | fp_func_multu | fp_func_div | fp_func_divu | 738 fp_func_cvtf2d | fp_func_cvtf2i | fp_func_cvtd2f | 739 fp_func_cvtd2i | fp_func_cvti2f | fp_func_cvti2d | 740 fp_func_eqf | fp_func_nef | fp_func_ltf | fp_func_gtf | 741 fp_func_lef | fp_func_gef | fp_func_eqd | fp_func_ned | 742 fp_func_ltd | fp_func_gtd | fp_func_led | fp_func_ged => 743 assert false 744 report "floating point instructions not implemented" severity warning; 745 when others => 746 assert false 747 report "undefined floating point instruction function" severity error; 748 end case; 749 when op_j => 750 do_MEM_jump; 751 when op_jr => 752 do_MEM_jump_reg; 753 when op_jal => 754 do_EX_link; 755 do_MEM_jump; 756 do_WB(natural_to_bv(link_reg, 5)); 757 when op_jalr => 758 do_EX_link; 759 do_MEM_jump_reg; 760 do_WB(natural_to_bv(link_reg, 5)); 761 when op_beqz | op_bnez => 762 do_EX_branch; 763 if branch_taken then 764 do_MEM_branch; 765 end if; 766 when op_bfpt => 767 assert false 768 report "BFPT instruction not implemented" severity warning; 769 when op_bfpf => 770 assert false 771 report "BFPF instruction not implemented" severity warning; 772 when op_addi | op_subi | 773 op_addui | op_subui | 774 op_andi | op_ori | op_xori | 775 op_slli | op_srli | op_srai => 776 do_EX_arith_logic_immed; 777 do_WB(IR_Itype_rd); 778 when op_lhi => 779 do_EX_lhi; 780 do_WB(IR_Itype_rd); 781 when op_rfe => 782 assert false 783 report "RFE instruction not implemented" severity warning; 784 when op_trap => 785 assert false 786 report "TRAP instruction encountered, execution halted" 787 severity note; 788 wait until phi1 = '1'; 789 halt <= '1' after Tpd_clk_ctrl; 790 wait until reset = '1'; 791 exit; 792 when op_seqi | op_snei | op_slti | 793 op_sgti | op_slei | op_sgei => 794 do_EX_set_signed(immed => true); 795 do_WB(IR_Itype_rd); 796 when op_lb => 797 assert false 798 report "LB instruction not implemented" severity warning; 799 when op_lh => 800 assert false 801 report "LH instruction not implemented" severity warning; 802 when op_lw => 803 do_EX_load_store; 804 do_MEM_load; 805 exit when reset = '1'; 806 do_WB(IR_Itype_rd); 807 when op_sw => 808 do_EX_load_store; 809 do_MEM_store; 810 exit when reset = '1'; 811 when op_lbu => 812 assert false 813 report "LBU instruction not implemented" severity warning; 814 when op_lhu => 815 assert false 816 report "LHU instruction not implemented" severity warning; 817 when op_sb => 818 assert false 819 report "SB instruction not implemented" severity warning; 820 when op_sh => 821 assert false 822 report "SH instruction not implemented" severity warning; 823 when op_lf => 824 assert false 825 report "LF instruction not implemented" severity warning; 826 when op_ld => 827 assert false 828 report "LD instruction not implemented" severity warning; 829 when op_sf => 830 assert false 831 report "SF instruction not implemented" severity warning; 832 when op_sd => 833 assert false 834 report "SD instruction not implemented" severity warning; 835 when op_sequi | op_sneui | op_sltui | 836 op_sgtui | op_sleui | op_sgeui => 837 do_EX_set_unsigned(immed => true); 838 do_WB(IR_Itype_rd); 839 when others => 840 assert false 841 report "undefined instruction" severity error; 842 end case; 843 -- 844 end loop; 845 -- 846 ---------------------------------------------------------------- 847 -- loop exited on reset 848 ---------------------------------------------------------------- 849 assert reset = '1' 850 report "Internal error: reset code reached with reset = '0'" 851 severity failure; 852 -- 853 -- start again 854 -- 855 end process sequencer; 856 857 858 end behaviour; 859
This page was generated using GHDL 0.14 (20040829) [Sokcho edition], a program written by Tristan Gingold