dlx/controller-behaviour.vhdl

    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