Gladiatorul21

Tema_AC

Jan 19th, 2022
866
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VeriLog 30.82 KB | None | 0 0
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date:    20:14:45 11/26/2011
  7. // Design Name:
  8. // Module Name:    uc
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module uc(
  22.         clk,
  23.         rst,
  24.         ri,
  25.         ind,
  26.         regs_addr,
  27.         regs_oe,
  28.         regs_we,
  29.         alu_oe,
  30.         alu_carry,
  31.         alu_opcode,
  32.         ram_oe,
  33.         ram_we,
  34.         io_oe,
  35.         io_we,
  36.         cp_oe,
  37.         cp_we,
  38.         ind_sel,
  39.         ind_oe,
  40.         ind_we,
  41.         am_oe,
  42.         am_we,
  43.         aie_oe,
  44.         aie_we,
  45.         t1_oe,
  46.         t1_we,
  47.         t2_oe,
  48.         t2_we,
  49.         ri_oe,
  50.         ri_we,
  51.         disp_state
  52.     );
  53.  
  54. parameter word_width =          16;
  55. parameter state_width =         16;
  56.  
  57. `define ADC                     0
  58. `define SBB1                    1
  59. `define SBB2                    2
  60. `define NOT                     3
  61. `define AND                     4
  62. `define OR                      5
  63. `define XOR                     6
  64. `define SHL                     7
  65. `define SHR                     8
  66. `define SAR                     9
  67.  
  68. `define RA                      0
  69. `define RB                      1
  70. `define RC                      2
  71. `define IS                      3
  72. `define XA                      4
  73. `define XB                      5
  74. `define BA                      6
  75. `define BB                      7
  76.  
  77. input                           clk;
  78. input                           rst;
  79. input [word_width-1 : 0]        ri;
  80. input [word_width-1 : 0]        ind;
  81. output reg                      alu_oe;
  82. output reg                      alu_carry;
  83. output reg[3 : 0]               alu_opcode;
  84. output reg                      ram_oe;
  85. output reg                      ram_we;
  86. output reg                      io_oe;
  87. output reg                      io_we;
  88. output reg[2 : 0]               regs_addr;
  89. output reg                      regs_oe;
  90. output reg                      regs_we;
  91. output reg                      cp_oe;
  92. output reg                      cp_we;
  93. output reg                      ind_sel;        // controls IND register input (0 = bus, 1 = alu flags)
  94. output reg                      ind_oe;
  95. output reg                      ind_we;
  96. output reg                      am_oe;
  97. output reg                      am_we;
  98. output reg                      aie_oe;
  99. output reg                      aie_we;
  100. output reg                      t1_oe;
  101. output reg                      t1_we;
  102. output reg                      t2_oe;
  103. output reg                      t2_we;
  104. output reg                      ri_oe;          // controls RI register output which generates the offset for Jcond instructions
  105. output reg                      ri_we;
  106. output[state_width-1 : 0]       disp_state;
  107.  
  108. wire [0:6]                      cop;
  109. wire                            d;
  110. wire [0:1]                      mod;
  111. wire [0:2]                      rg;
  112. wire [0:2]                      rm;
  113.  
  114. assign cop  = {ri[0], ri[1], ri[2], ri[3], ri[4], ri[5], ri[6]};
  115. assign d    = {ri[7]};
  116. assign mod  = {ri[8], ri[9]};
  117. assign rg   = {ri[10], ri[11], ri[12]};
  118. assign rm   = {ri[13], ri[14], ri[15]};
  119.  
  120. `define reset                   'h00            // reset state
  121. `define fetch                   'h10            // load instruction to instruction register
  122. `define decode                  'h20            // analyze loaded instruction
  123. `define addr_sum                'h30            // computes address of the form [By+Xz] with y,z in {A, B}
  124. `define addr_reg                'h34            // computes address of the form [yz] with y in {X, B} and z in {A, B}
  125. `define load_src_reg            'h40            // load source operand from register
  126. `define load_src_mem            'h44            // load source operand from memory
  127. `define load_dst_reg            'h50            // load destination operand from register
  128. `define load_dst_mem            'h54            // load destination operand from memory
  129. `define exec_1op                'h60            // execute 1 operand instructions
  130. `define exec_2op                'h64            // execute 2 operand instructions
  131. `define transfer                      'h68              // executa instructiuni de transfer
  132. `define store_reg               'h70            // store result to register
  133. `define store_mem               'h74            // store result to memory
  134. `define inc_cp                  'h80            // increment program counter
  135.  
  136. `define decrement_IS                  'h90              // se implementeaza instructiunea PUSH
  137. `define increment_IS                  'h100             // se implementeaza instructiunea POP
  138. `define addr_reg_deplasata      'h110               // implementare calcul adresa [XA/XB/BA/BB + Deplasament]
  139. `define addr_sum_deplasata      'h120               // implementare calcul adresa [BA + XA/XB / BB + XA/XB + Deplasament]
  140. `define load_operand_imediat      'h130             // memoreaza operandul imediat in T2
  141. `define skip_load_src             'h140             // se sare peste incarcarea registrului sursa
  142. `define skip_load_dst             'h150             // se sare peste incarcarea registrului destinatie
  143. `define jmp                           'h160             // se implementeaza instructiunea JMP      
  144. `define call                          'h170             // se implementeaza instructiunea CALL
  145. `define jcond                         'h180             // se implementeaza instructiunea JCOND
  146. `define skip_store                'h190             // to delete
  147. `define addr_autodecrement        'h200             // implenentare adresare cu autodecrementare
  148. `define addr_indirect             'h210             // implementare adresare indirecta
  149. `define ret                           'h220             // se implementeaza instructiunea RET
  150. `define pushf                         'h230             // se implementeaza instructiunea PUSHF
  151. `define popf                          'h240             // se implementeaza instructiunea POPF
  152. `define addr_autoincrement        'h250             // implenentare adresare cu autoincrementare
  153. `define addr_2x_indirect          'h260             // implementere adresare dublu indirecta
  154.  
  155. reg [state_width-1 : 0] state = `reset, state_next;
  156. reg [state_width-1 : 0] decoded_src, decoded_src_next;      // stores decoded source operand load state
  157. reg [state_width-1 : 0] decoded_dst, decoded_dst_next;      // stores decoded destination operand load state
  158. reg [state_width-1 : 0] decoded_exec, decoded_exec_next;    // stores decoded execute state
  159. reg [state_width-1 : 0] decoded_store, decoded_store_next;  // stores decoded store state
  160.  
  161. reg decoded_d, decoded_d_next;                              // stores decoded direction bit
  162.  
  163.  
  164. // FSM - sequential part
  165. always @(posedge clk) begin
  166.     state <= `reset;
  167.  
  168.     if(!rst) begin
  169.         state <= state_next;
  170.  
  171.         if(state == `decode) begin
  172.             decoded_src <= decoded_src_next;
  173.             decoded_dst <= decoded_dst_next;
  174.             decoded_exec <= decoded_exec_next;
  175.             decoded_store <= decoded_store_next;
  176.             decoded_d <= decoded_d_next;
  177.         end
  178.     end
  179. end
  180.  
  181. // FSM - combinational part
  182. always @(*) begin
  183.     state_next = `reset;
  184.     decoded_src_next = `reset;
  185.     decoded_dst_next = `reset;
  186.     decoded_exec_next = `reset;
  187.     decoded_store_next = `reset;
  188.     decoded_d_next = 0;
  189.     alu_oe = 0;
  190.     alu_carry = 0;
  191.     alu_opcode = 0;
  192.     ram_oe = 0;
  193.     ram_we = 0;
  194.     io_oe = 0;
  195.     io_we = 0;
  196.     regs_addr = 0;
  197.     regs_oe = 0;
  198.     regs_we = 0;
  199.     cp_oe = 0;
  200.     cp_we = 0;
  201.     ind_sel = 0;
  202.     ind_oe = 0;
  203.     ind_we = 0;
  204.     am_oe = 0;
  205.     am_we = 0;
  206.     aie_oe = 0;
  207.     aie_we = 0;
  208.     t1_oe = 0;
  209.     t1_we = 0;
  210.     t2_oe = 0;
  211.     t2_we = 0;
  212.     ri_oe = 0;
  213.     ri_we = 0;
  214.  
  215.     case(state)
  216.         `reset: begin
  217.             state_next = `fetch;
  218.         end
  219.  
  220.         `fetch: begin
  221.             cp_oe = 1;
  222.             am_we = 1;
  223.  
  224.             state_next = `fetch + 1;
  225.         end
  226.  
  227.         `fetch + 'd1: begin
  228.             am_oe = 1;
  229.  
  230.             state_next = `fetch + 2;
  231.         end
  232.  
  233.         `fetch + 'd2: begin
  234.             ram_oe = 1;
  235.             ri_we = 1;
  236.  
  237.             state_next = `decode;
  238.         end
  239.  
  240. //-----------------------------------------------------------------------//
  241. //Decode section
  242.  
  243.         `decode: begin
  244.                
  245.                 // data transfer / control
  246.                 if(cop[0:3] == 4'b0000)
  247.                 begin
  248.                    
  249.                     if(cop[4:6] == 3'b000)  // MOV
  250.                     begin
  251.                         decoded_d_next = d;
  252.                                            
  253.                         decoded_exec_next = `transfer;
  254.                        
  255.                         decoded_dst_next = (mod == 2'b11) || (d == 1) ? `load_dst_reg : `load_dst_mem;
  256.                         decoded_src_next = (mod == 2'b11) || (d == 0) ? `load_src_reg : `load_src_mem;
  257.                        
  258.                         decoded_store_next = (mod == 2'b11) || (d == 1) ? `store_reg : `store_mem;
  259.                        
  260.                     end
  261.                    
  262.                     else if(cop[4:6] == 3'b010) // PUSH
  263.                     begin
  264.                        
  265.                         decoded_d_next = 0;
  266.                                        
  267.                         decoded_exec_next = `decrement_IS;
  268.    
  269.                         decoded_dst_next = (mod == 2'b11) ? `load_dst_reg : `load_dst_mem;
  270.                         decoded_src_next = `skip_load_src;
  271.        
  272.                         decoded_store_next = `store_mem;
  273.                     end
  274.                    
  275.                     else if(cop[4:6] == 3'b011) // POP
  276.                     begin
  277.                         decoded_d_next = 0;
  278.                                            
  279.                         decoded_exec_next = `increment_IS;
  280.                        
  281.                         decoded_dst_next = (mod != 2'b11) ? `skip_load_dst : `load_dst_reg;
  282.                         decoded_src_next = `skip_load_src;
  283.                        
  284.                         decoded_store_next = (mod == 2'b11) ? `store_reg : `store_mem;
  285.                     end
  286.                    
  287.                     else if(cop[4:6] == 3'b100) // CALL
  288.                     begin
  289.                         decoded_d_next = 0;
  290.                        
  291.                         decoded_exec_next = `call;
  292.                        
  293.                         decoded_dst_next = (mod != 2'b11) ? `skip_load_dst : `load_dst_reg;
  294.                         decoded_src_next = `skip_load_src;
  295.                        
  296.                         decoded_store_next = (mod == 2'b11) ? `store_reg : `store_mem;
  297.                     end
  298.                    
  299.                     else if(cop[4:6] == 3'b101) // JMP
  300.                     begin
  301.                         decoded_d_next = 0;
  302.                                            
  303.                         decoded_exec_next = `jmp;
  304.                        
  305.                         decoded_dst_next = (mod != 2'b11) ? `skip_load_dst : `load_dst_reg;
  306.                         decoded_src_next = `skip_load_src;
  307.                        
  308.                         decoded_store_next = (mod == 2'b11) ? `store_reg : `store_mem;
  309.  
  310.                     end
  311.                    
  312.                 end
  313.          
  314.                 // MOV cu operand imediat
  315.                 else if(cop[0:3] == 3'b0010)
  316.                 begin
  317.                     decoded_d_next = 0;
  318.                    
  319.                     decoded_exec_next = `transfer;
  320.                    
  321.                     decoded_dst_next = mod == 2'b11 ? `load_dst_reg : `load_dst_mem;
  322.                     decoded_src_next = `load_operand_imediat;
  323.                    
  324.                     decoded_store_next = (mod == 2'b11) ? `store_reg : `store_mem;
  325.                
  326.                 end
  327.          
  328.             // decode location of operands and operation
  329.             else if(cop[0:3] == 4'b0001) // one operand instructions
  330.                 begin          
  331.                 decoded_d_next      = 0;
  332.                 decoded_dst_next    = mod == 2'b11 ? `load_dst_reg : `load_dst_mem;
  333.                 decoded_src_next    = decoded_dst_next;
  334.                 decoded_exec_next   = `exec_1op;
  335.                 decoded_store_next  = mod == 2'b11 ? `store_reg : `store_mem;
  336.             end
  337.                
  338.             else if(cop[0:2] == 3'b010) // two operand instructions
  339.                 begin      
  340.                 decoded_d_next      = d;
  341.                 decoded_dst_next    = (mod == 2'b11) || (d == 1) ? `load_dst_reg : `load_dst_mem;
  342.                 decoded_src_next    = (mod == 2'b11) || (d == 0) ? `load_src_reg : `load_src_mem;
  343.                 decoded_exec_next   = `exec_2op;
  344.                 decoded_store_next  = !cop[3] ? `skip_store : ((mod == 2'b11) || (d == 1) ? `store_reg : `store_mem);
  345.             end
  346.            
  347.                 else if(cop[0:2] == 3'b011) // two operand instruction - adresare imediata
  348.                 begin
  349.                      decoded_d_next = 0;
  350.                      decoded_dst_next = (mod == 2'b11) ? `load_dst_reg : `load_dst_mem;
  351.                      decoded_src_next = `load_operand_imediat;
  352.                      decoded_exec_next = `exec_2op;
  353.                      decoded_store_next = (!cop[3]) ? `skip_store : ((mod == 2'b11) ? `store_reg : `store_mem);
  354.                
  355.                 end
  356.                    
  357.                 else if(cop[0:3] == 4'b1001) // JCOND
  358.                 begin
  359.                        
  360.                     state_next = `jcond;
  361.                        
  362.                 end
  363.                    
  364.                 else if(cop[0:3] == 4'b1000)
  365.                 begin
  366.                        
  367.                         if(cop[4:6] == 3'b100) // RET
  368.                         begin
  369.                        
  370.                             state_next = `ret;
  371.                            
  372.                         end
  373.                        
  374.                         if(cop[4:6] == 3'b010) // PUSHF
  375.                         begin
  376.                            
  377.                             state_next = `pushf;
  378.                            
  379.                         end
  380.                        
  381.                         if(cop[4:6] == 3'b011) // POPF
  382.                         begin
  383.                        
  384.                             state_next = `popf;
  385.                        
  386.                         end
  387.                        
  388.                 end
  389.                                
  390.             // decode address calculation mode
  391.                 if(cop[0] == 0)
  392.                 begin
  393.                     case(mod)
  394.                          
  395.                          2'b00:
  396.                          begin
  397.                                 state_next = rm[0] ? `addr_reg : `addr_sum;
  398.                          end
  399.  
  400.                          2'b01:
  401.                          begin
  402.                                
  403.                                 if(rm[0] == 0)
  404.                                 begin
  405.                                     state_next = `addr_autoincrement;
  406.                                 end
  407.                                
  408.                                 else if(rm[1] == 0)
  409.                                 begin
  410.                                     state_next = `addr_autodecrement;
  411.                                 end
  412.                                
  413.                                 else if(rm[2] == 0)
  414.                                 begin
  415.                                     state_next = `addr_indirect;
  416.                                 end
  417.                                
  418.                                 else
  419.                                 begin
  420.                                     state_next = `addr_2x_indirect;
  421.                                 end
  422.                                
  423.                                                                
  424.                          end
  425.  
  426.                          2'b10:
  427.                          begin
  428.                                 state_next = rm[0] ? `addr_reg_deplasata : `addr_sum_deplasata;
  429.                          end
  430.                          
  431.                          2'b11:
  432.                          begin
  433.                                 state_next = decoded_src_next;
  434.                          end
  435.                          
  436.                     endcase
  437.                 end
  438.                
  439.                
  440.                
  441.         end
  442.  
  443. //-----------------------------------------------------------------------//
  444. //Addresing of type [BA + XA/XB / BB + XA/XB + Deplasament]
  445.  
  446.           `addr_sum_deplasata:
  447.           begin
  448.                
  449.                 regs_addr = rm[1] ? `BB : `BA;
  450.             regs_oe = 1;
  451.             t1_we = 1;
  452.                
  453.                 state_next = `addr_sum_deplasata + 1;
  454.                
  455.           end
  456.          
  457.           `addr_sum_deplasata + 'd1:
  458.           begin
  459.                
  460.                 regs_addr = rm[2] ? `XB : `XA;
  461.             regs_oe = 1;
  462.             t2_we = 1;
  463.  
  464.             state_next = `addr_sum_deplasata + 2;
  465.                
  466.           end
  467.          
  468.           // realizam suma dintre T1 si T2 pe care o introducem in T1
  469.           // aceasta suma va reprezenta suma registrilor, la care urmeaza
  470.           // sa adaugam deplasamentul
  471.           `addr_sum_deplasata + 'd2:
  472.           begin
  473.                
  474.                 t1_oe = 1;
  475.                 t2_oe = 1;
  476.                
  477.                 alu_carry = 0;
  478.                 alu_opcode = `ADC;
  479.                 alu_oe = 1;
  480.                
  481.                 t1_we = 1;
  482.                
  483.                 state_next = `addr_sum_deplasata + 3;
  484.                
  485.           end
  486.          
  487.           // se muta in T2 valoarea din registrul cp in scopul incrementarii ei
  488.           `addr_sum_deplasata + 'd3:
  489.           begin
  490.                
  491.                 cp_oe = 1;
  492.                
  493.                 t2_we = 1;
  494.                
  495.                 state_next = `addr_sum_deplasata + 4;
  496.                
  497.           end
  498.          
  499.           // se incrementeaza cp
  500.           `addr_sum_deplasata + 'd4:
  501.           begin
  502.                
  503.                 t2_oe = 1; 
  504.                 alu_oe = 1;
  505.                
  506.                 cp_we = 1;
  507.                
  508.                 alu_carry = 1;
  509.                 alu_opcode = `ADC;
  510.                
  511.                 state_next = `addr_sum_deplasata + 5;
  512.                
  513.           end
  514.          
  515.           // se scrie in am valoarea din cp in scopul obtinerii deplasamentului
  516.           `addr_sum_deplasata + 'd5:
  517.           begin
  518.                
  519.                 cp_oe = 1;
  520.                 am_we = 1;
  521.                
  522.                 state_next = `addr_sum_deplasata + 6;
  523.          
  524.           end
  525.          
  526.           `addr_sum_deplasata + 'd6:
  527.           begin
  528.                
  529.                 am_oe = 1;
  530.                            
  531.                 state_next = `addr_sum_deplasata + 7;
  532.                
  533.           end
  534.          
  535.           // in urm 2 stari se obtine deplasamentul din memorie, si se memoreaza in T2
  536.           `addr_sum_deplasata + 'd7:
  537.           begin
  538.                
  539.                 ram_oe = 1;
  540.                 t2_we = 1;
  541.                
  542.                 state_next = `addr_sum_deplasata + 8;
  543.                
  544.           end
  545.          
  546.           // prin suma dintre T1 si T2, se obtine valoarea adresei finale
  547.           `addr_sum_deplasata + 'd8:
  548.           begin
  549.                    
  550.                 t1_oe = 1;
  551.                 t2_oe = 1;
  552.                
  553.                 alu_carry = 0;
  554.                 alu_opcode = `ADC;
  555.                 alu_oe = 1;
  556.                
  557.                 if(decoded_d)
  558.                 t2_we = 1;
  559.             else
  560.                 t1_we = 1;
  561.                
  562.                 state_next = decoded_src;
  563.          
  564.           end
  565.  
  566. //-----------------------------------------------------------------------//
  567. //Indirect addressing
  568.          
  569.           // pentru cazul adresarii indirecte, vom lua din memoria RAM operandul
  570.          
  571.           // incrementam CP, si il punem in AM pentru a citi urmatorul cuvant,
  572.           // care reprezinta operandul
  573.           `addr_indirect:
  574.           begin
  575.                
  576.                 cp_oe = 1;
  577.                 t1_we = 1;
  578.                
  579.                 state_next = `addr_indirect + 1;
  580.                
  581.           end
  582.          
  583.           `addr_indirect + 'd1:
  584.           begin
  585.          
  586.                 t1_oe = 1;
  587.                 t2_oe = 0;
  588.                
  589.                 alu_carry = 1;
  590.                 alu_opcode = `ADC;
  591.                
  592.                 alu_oe = 1;
  593.                
  594.                 am_we = 1;
  595.                 cp_we = 1;
  596.                
  597.                 state_next = `addr_indirect + 2;
  598.                
  599.           end
  600.          
  601.           `addr_indirect + 'd2:
  602.           begin
  603.                
  604.                 am_oe = 1;
  605.                
  606.                 state_next = `addr_indirect + 3;
  607.          
  608.           end
  609.          
  610.           `addr_indirect + 'd3:
  611.           begin
  612.                
  613.                 ram_oe = 1;
  614.                
  615.                 if(decoded_d)
  616.                     t2_we = 1;
  617.                 else
  618.                     t1_we = 1;
  619.                    
  620.                 state_next = decoded_src;
  621.          
  622.           end
  623.  
  624. //-----------------------------------------------------------------------//
  625. //Double indirect addressing
  626.  
  627.           // In cazul deplasarii dublu indirecte, operandul va fi luat tot din RAM
  628.          
  629.           // incrementam CP, il punem in AM pentru a citi urmatorul cuvant
  630.           // urmatorul cuvant, il punem din nou in AM, pentru a obtine operandul
  631.          
  632.           // incrementare CP
  633.           `addr_2x_indirect:
  634.           begin
  635.                
  636.                 t1_we = 1;
  637.                 cp_oe = 1;
  638.                
  639.                 state_next = `addr_2x_indirect + 1;
  640.                
  641.           end
  642.          
  643.           `addr_2x_indirect + 'd1:
  644.           begin
  645.                
  646.                 t1_oe = 1;
  647.                 t2_oe = 0;
  648.                
  649.                 alu_oe = 1;
  650.                 cp_we = 1;
  651.                
  652.                 alu_carry = 1;
  653.                 alu_opcode = `ADC;
  654.                
  655.                 state_next = `addr_2x_indirect + 2;
  656.          
  657.           end
  658.          
  659.           // introducem in AM CP+1 pentru a obtine urmatorul cuvant
  660.           `addr_2x_indirect + 'd2:
  661.           begin
  662.                
  663.                 am_we = 1;
  664.                 cp_oe = 1;
  665.                
  666.                 state_next = `addr_2x_indirect + 3;
  667.                
  668.           end
  669.          
  670.           `addr_2x_indirect + 'd3:
  671.           begin
  672.                
  673.                 am_oe = 1;
  674.                
  675.                 state_next = `addr_2x_indirect + 4;
  676.                
  677.           end
  678.          
  679.           // cuvantul obtinut se introduce tot in AM, pentru a obtine operandul
  680.           `addr_2x_indirect + 'd4:
  681.           begin
  682.          
  683.                 am_we = 1;
  684.                 ram_oe = 1;
  685.                
  686.                 state_next = `addr_2x_indirect + 5;
  687.          
  688.           end
  689.          
  690.           `addr_2x_indirect + 'd5:
  691.           begin
  692.                
  693.                 am_oe = 1;
  694.                
  695.                 state_next = `addr_2x_indirect + 6;
  696.                
  697.           end
  698.          
  699.           `addr_2x_indirect + 'd6:
  700.           begin
  701.                
  702.                 ram_oe = 1;
  703.                
  704.                 if(decoded_d)
  705.                     t2_we = 1;
  706.                 else
  707.                     t1_we = 1;
  708.                
  709.                 state_next = decoded_src;
  710.          
  711.           end
  712.  
  713. //-----------------------------------------------------------------------//
  714. //Indirect addressing - reg sum - autodecrement
  715.  
  716.           // Adresa efectiva va fi adresa obtinuta prin insumarea
  717.           // BB/BA + XA, unde XA este valoarea obtinuta dupa decrementare
  718.          
  719.           `addr_autodecrement:
  720.           begin
  721.          
  722.                 regs_addr = rm[2] ? `BB : `BA;
  723.                 regs_oe = 1;
  724.                
  725.                 t1_we = 1;
  726.                
  727.                 state_next = `addr_autodecrement + 1;
  728.          
  729.           end
  730.          
  731.           // se decrementeaza XA
  732.           `addr_autodecrement + 'd1:
  733.           begin
  734.                
  735.                 regs_addr = `XA;
  736.                 regs_oe = 1;
  737.                
  738.                 t2_we = 1;
  739.                
  740.                 state_next = `addr_autodecrement + 2;
  741.          
  742.           end
  743.          
  744.           `addr_autodecrement + 'd2:
  745.           begin
  746.                
  747.                 t2_oe = 1;
  748.                 t1_oe = 0;
  749.                
  750.                 regs_addr = `XA;
  751.                 regs_we = 1;
  752.                
  753.                 alu_carry = 1;
  754.                 alu_opcode = `SBB2;
  755.                
  756.                 alu_oe = 1;
  757.  
  758.                 state_next = `addr_autodecrement + 3;
  759.                
  760.           end
  761.          
  762.           // urmarim sa realizam suma dintre XA decrementat si BB/BA
  763.           `addr_autodecrement + 'd3:
  764.           begin
  765.          
  766.                 t2_we = 1;
  767.                
  768.                 regs_addr = `XA;
  769.                 regs_oe = 1;
  770.                
  771.                 state_next = `addr_autodecrement + 4;
  772.          
  773.           end
  774.          
  775.           `addr_autodecrement + 'd4:
  776.           begin
  777.                
  778.                 t1_oe = 1;
  779.                 t2_oe = 1;
  780.                
  781.                 alu_opcode = `ADC;
  782.                 alu_oe = 1;
  783.                
  784.                 if(decoded_d)
  785.                     t2_we = 1;
  786.                 else
  787.                     t1_we = 1;
  788.                    
  789.                 state_next = decoded_src;
  790.          
  791.           end
  792.          
  793.         `addr_reg: begin
  794.             regs_addr = rm;
  795.             regs_oe = 1;
  796.             if(decoded_d)
  797.                 t2_we = 1;
  798.             else
  799.                 t1_we = 1;
  800.  
  801.             state_next = decoded_src;
  802.         end
  803.  
  804. //-----------------------------------------------------------------------//
  805. //Indirect addressing - reg sum - autoincrement
  806.  
  807.           // Adresa efectiva va fi adresa obtinuta prin insumarea BA/BB + XA/XB
  808.           // iar apoi XA/XB se incrementeaza
  809.          
  810.           // Initial vom realiza suma dintre registre, iar apoi vom incrementa XA si XB
  811.           `addr_autoincrement:
  812.           begin
  813.                
  814.                 regs_addr = rm[1] ? `BB : `BA;
  815.                 regs_oe = 1;
  816.                
  817.                 t1_we = 1;
  818.                
  819.                 state_next = `addr_autoincrement + 1;              
  820.                
  821.           end
  822.          
  823.           `addr_autoincrement + 'd1:
  824.           begin
  825.                
  826.                 regs_addr = rm[2] ? `XB : `XA;
  827.                 regs_oe = 1;
  828.                
  829.                 t2_we = 1;
  830.                
  831.                 state_next = `addr_autoincrement + 2;              
  832.                
  833.           end
  834.          
  835.           // realizez suma dintre registrii
  836.           `addr_autoincrement + 'd2:
  837.           begin
  838.                
  839.                 t1_oe = 1;
  840.                 t2_oe = 1;
  841.                
  842.                 alu_opcode = `ADC;
  843.                 alu_oe = 1;
  844.                
  845.                 if(decoded_d)
  846.                     t2_we = 1;
  847.                 else
  848.                     t1_we = 1;
  849.                    
  850.                 state_next = `addr_autoincrement + 3;
  851.          
  852.           end
  853.          
  854.           // se introduce XA sau XB in registrul ramas liber pentru a fi incrementat
  855.           `addr_autoincrement + 'd3:
  856.           begin
  857.                
  858.                 regs_addr = rm[2] ? `XB : `XA;
  859.                 regs_oe = 1;
  860.                
  861.                 if(decoded_d)      
  862.                     t1_we = 1;
  863.                 else
  864.                     t2_we = 1;
  865.                
  866.                 state_next = `addr_autoincrement + 4;
  867.          
  868.           end
  869.          
  870.           `addr_autoincrement + 'd4:
  871.           begin
  872.                
  873.                 regs_addr = rm[2] ? `XB : `XA;
  874.                 regs_we = 1;
  875.                
  876.                 alu_carry = 1;
  877.                 alu_opcode = `ADC;
  878.                
  879.                 alu_oe = 1;
  880.                
  881.                 if(decoded_d)
  882.                 begin
  883.                    
  884.                     t1_oe = 1;
  885.                     t2_oe = 0;
  886.                                        
  887.                 end
  888.                
  889.                 else
  890.                 begin
  891.                    
  892.                     t1_oe = 0;
  893.                     t2_oe = 1;
  894.                    
  895.                 end
  896.                
  897.                 state_next = decoded_src;
  898.                                
  899.           end
  900.  
  901. //-----------------------------------------------------------------------//
  902. //Memorarea operandului imediat
  903.  
  904.           // Se urmareste memorarea in T2 a operandului imediat, in scopul
  905.           // implementarii operatiilor cu operand imediat
  906.          
  907.           // Urmarim prima data incrementarea CP, pentru a obtine operandul
  908.           // de la adresa CP + 1
  909.           `load_operand_imediat:
  910.           begin
  911.                
  912.                 cp_oe = 1;
  913.                 t2_we = 1;
  914.                
  915.                 state_next = `load_operand_imediat + 1;
  916.                
  917.           end
  918.          
  919.           // Se obtine CP+1 si se trimite in CP si in AM
  920.           `load_operand_imediat + 'd1:
  921.           begin
  922.                
  923.                 t2_oe = 1;
  924.                 alu_oe = 1;
  925.                
  926.                 alu_carry = 1;
  927.                 alu_opcode = `ADC;
  928.                
  929.                 cp_we = 1;
  930.                 am_we = 1;
  931.                
  932.                 state_next = `load_operand_imediat + 2;
  933.                
  934.           end
  935.          
  936.           `load_operand_imediat + 'd2:
  937.           begin
  938.          
  939.                 am_oe = 1;
  940.                
  941.                 state_next = `load_operand_imediat + 3;
  942.          
  943.           end
  944.          
  945.           // Obtinem din RAM valoarea operandului imediat, pe care o memoram in T2
  946.           `load_operand_imediat + 'd3:
  947.           begin
  948.                
  949.                 ram_oe = 1;
  950.                 t2_we = 1;
  951.                
  952.                 state_next = decoded_dst;
  953.                
  954.           end
  955.          
  956.         `load_src_reg: begin
  957.             regs_addr = decoded_d ? rm : rg;
  958.             regs_oe = 1;
  959.             t2_we = 1;
  960.  
  961.             state_next = decoded_dst;
  962.         end
  963.        
  964.         `load_src_mem: begin
  965.             t1_oe = 0;
  966.             t2_oe = 1;
  967.             alu_opcode = `OR;
  968.             alu_oe = 1;
  969.             am_we = 1;
  970.  
  971.             state_next = `load_src_mem + 1;
  972.         end
  973.  
  974.         `load_src_mem + 'd1: begin
  975.             am_oe = 1;
  976.  
  977.             state_next = `load_src_mem + 2;
  978.         end
  979.  
  980.         `load_src_mem + 'd2: begin
  981.             ram_oe = 1;
  982.             t2_we = 1;
  983.  
  984.             state_next = decoded_dst;
  985.         end
  986.  
  987.         `load_dst_reg: begin
  988.             regs_addr = decoded_d ? rg : rm;
  989.             regs_oe = 1;
  990.             t1_we = 1;
  991.  
  992.             state_next = decoded_exec;
  993.         end
  994.        
  995.         `load_dst_mem: begin
  996.             t1_oe = 1;
  997.             t2_oe = 0;
  998.             alu_opcode = `OR;
  999.             alu_oe = 1;
  1000.             am_we = 1;
  1001.  
  1002.             state_next = `load_dst_mem + 1;
  1003.         end
  1004.  
  1005.         `load_dst_mem + 'd1: begin
  1006.             am_oe = 1;
  1007.  
  1008.             state_next = `load_dst_mem + 2;
  1009.         end
  1010.  
  1011.         `load_dst_mem + 'd2: begin
  1012.             ram_oe = 1;
  1013.             t1_we = 1;
  1014.  
  1015.             state_next = decoded_exec;
  1016.         end
  1017.          
  1018.           // atunci cand folosim doar T1 si utilizam un singur operand
  1019.           // sarim incarcarea T2
  1020.           `skip_load_src:
  1021.           begin
  1022.          
  1023.                 state_next = decoded_dst;
  1024.                
  1025.           end
  1026.          
  1027.           // atunci cand folosim doar T2 si utilizam un singur operand
  1028.           // sarim incarcarea T1
  1029.           `skip_load_dst:
  1030.           begin
  1031.          
  1032.                 state_next = decoded_exec;
  1033.                
  1034.           end
  1035.  
  1036.         `exec_1op: begin
  1037.             t1_oe = 1;
  1038.             case(cop[4:6])
  1039.                 3'b000: begin                               // INC
  1040.                     alu_carry = 1;
  1041.                     alu_opcode = `ADC;
  1042.                 end
  1043.                 3'b001: begin                               // DEC
  1044.                     alu_carry = 1;
  1045.                     alu_opcode = `SBB1;
  1046.                 end
  1047.                 3'b010: begin                               // NEG
  1048.                     alu_carry = 0;
  1049.                     alu_opcode = `SBB2;
  1050.                 end
  1051.                 3'b011: begin                               // NOT
  1052.                     alu_opcode = `NOT;
  1053.                 end
  1054.                 3'b100: alu_opcode = `SHL;                  // SHL/SAL
  1055.                 3'b101: alu_opcode = `SHR;                  // SHR
  1056.                 3'b110: alu_opcode = `SAR;                  // SAR
  1057.             endcase
  1058.             alu_oe = 1;
  1059.             t1_we = 1;
  1060.             ind_sel = 1;
  1061.             ind_we = 1;
  1062.  
  1063.             state_next = decoded_store;
  1064.         end
  1065.        
  1066.         `exec_2op: begin
  1067.             t1_oe = 1;
  1068.             t2_oe = 1;
  1069.             case(cop[4:6])
  1070.                 3'b000: begin                               // ADD
  1071.                     alu_carry = 0;
  1072.                     alu_opcode = `ADC;
  1073.                 end
  1074.                 3'b001: begin                               // ADC
  1075.                     alu_carry = ind[0];
  1076.                     alu_opcode = `ADC;
  1077.                 end
  1078.                 3'b010: begin                               // SUB/CMP
  1079.                     alu_carry = 0;
  1080.                     alu_opcode = `SBB1;
  1081.                 end
  1082.                 3'b011: begin                               // SBB
  1083.                     alu_carry = ind[0];
  1084.                     alu_opcode = `SBB1;
  1085.                 end
  1086.                 3'b100: alu_opcode = `AND;                  // AND/TEST
  1087.                 3'b101: alu_opcode = `OR;                   // OR
  1088.                 3'b110: alu_opcode = `XOR;                  // XOR
  1089.             endcase
  1090.             alu_oe = 1;
  1091.             t1_we = 1;
  1092.             ind_sel = 1;
  1093.             ind_we = 1;
  1094.  
  1095.             state_next = decoded_store;
  1096.         end
  1097.        
  1098.         // Sarim peste etapa de stocare
  1099.         `skip_store:
  1100.         begin
  1101.        
  1102.             state_next = `inc_cp;
  1103.        
  1104.         end
  1105.        
  1106.         `store_reg: begin
  1107.             t1_oe = 1;
  1108.             t2_oe = 0;
  1109.             alu_opcode = `OR;
  1110.             alu_oe = 1;
  1111.             regs_addr = decoded_d ? rg : rm;
  1112.             regs_we = 1;
  1113.  
  1114.             state_next = `inc_cp;
  1115.         end
  1116.        
  1117.         `store_mem: begin
  1118.             t1_oe = 1;
  1119.             t2_oe = 0;
  1120.             alu_opcode = `OR;
  1121.             alu_oe = 1;
  1122.             am_oe = 1;
  1123.             ram_we = 1;
  1124.  
  1125.             state_next = `store_mem + 1;
  1126.         end
  1127.  
  1128.         `store_mem + 'd1: begin
  1129.             state_next = `inc_cp;
  1130.         end
  1131.  
  1132.         `inc_cp: begin
  1133.             cp_oe = 1;
  1134.             t1_we = 1;
  1135.  
  1136.             state_next = `inc_cp + 1;
  1137.         end
  1138.  
  1139.         `inc_cp + 'd1: begin
  1140.             t1_oe = 1;
  1141.             cp_we = 1;
  1142.             alu_oe = 1;
  1143.             alu_carry = 1;
  1144.             alu_opcode = `ADC;
  1145.  
  1146.             state_next = `fetch;
  1147.         end
  1148.  
  1149.         default: ;
  1150.     endcase
  1151. end
  1152.  
  1153. assign disp_state = state;
  1154.  
  1155. endmodule
  1156.  
  1157.        
  1158.         `load_src: begin
  1159.             regs_addr = decoded_d ? rm : rg;
  1160.             regs_oe = 1;
  1161.             t2_we = 1;
  1162.  
  1163.             state_next = `load_dst;
  1164.         end
  1165.        
  1166.         `load_dst: begin
  1167.             regs_addr = decoded_d ? rg : rm;
  1168.             regs_oe = 1;
  1169.             t1_we = 1;
  1170.  
  1171.             state_next = decoded_exec;
  1172.         end
  1173.  
  1174.         `exec_1op: begin
  1175.             t1_oe = 1;
  1176.             case(cop[4:6])
  1177.                 3'b000: begin                               // INC
  1178.                     alu_carry = 1;
  1179.                     alu_opcode = `ADC;
  1180.                 end
  1181.                 3'b001: begin                               // DEC
  1182.                     alu_carry = 1;
  1183.                     alu_opcode = `SBB1;
  1184.                 end
  1185.                 3'b010: begin                               // NEG
  1186.                     alu_carry = 0;
  1187.                     alu_opcode = `SBB2;
  1188.                 end
  1189.                 3'b011: begin                               // NOT
  1190.                     alu_opcode = `NOT;
  1191.                 end
  1192.                 3'b100: alu_opcode = `SHL;                  // SHL/SAL
  1193.                 3'b101: alu_opcode = `SHR;                  // SHR
  1194.                 3'b110: alu_opcode = `SAR;                  // SAR
  1195.             endcase
  1196.             alu_oe = 1;
  1197.             t1_we = 1;
  1198.             ind_sel = 1;
  1199.             ind_we = 1;
  1200.  
  1201.             state_next = decoded_store;
  1202.         end
  1203.  
  1204.         `exec_2op: begin
  1205.             t1_oe = 1;
  1206.             t2_oe = 1;
  1207.             case(cop[4:6])
  1208.                 3'b000: begin                               // ADD
  1209.                     alu_carry = 0;
  1210.                     alu_opcode = `ADC;
  1211.                 end
  1212.                 3'b001: begin                               // ADC
  1213.                     alu_carry = ind[0];
  1214.                     alu_opcode = `ADC;
  1215.                 end
  1216.                 3'b010: begin                               // SUB/CMP
  1217.                     alu_carry = 0;
  1218.                     alu_opcode = `SBB1;
  1219.                 end
  1220.                 3'b011: begin                               // SBB
  1221.                     alu_carry = ind[0];
  1222.                     alu_opcode = `SBB1;
  1223.                 end
  1224.                 3'b100: alu_opcode = `AND;                  // AND/TEST
  1225.                 3'b101: alu_opcode = `OR;                   // OR
  1226.                 3'b110: alu_opcode = `XOR;                  // XOR
  1227.             endcase
  1228.             alu_oe = 1;
  1229.             t1_we = 1;
  1230.             ind_sel = 1;
  1231.             ind_we = 1;
  1232.  
  1233.             state_next = decoded_store;
  1234.         end
  1235.  
  1236.         `store: begin
  1237.             t1_oe = 1;
  1238.             t2_oe = 0;
  1239.             alu_opcode = `OR;
  1240.             alu_oe = 1;
  1241.             regs_addr = decoded_d ? rg : rm;
  1242.             regs_we = 1;
  1243.  
  1244.             state_next = `inc_cp;
  1245.         end
  1246.  
  1247.         `inc_cp: begin
  1248.             cp_oe = 1;
  1249.             t1_we = 1;
  1250.  
  1251.             state_next = `inc_cp + 1;
  1252.         end
  1253.  
  1254.         `inc_cp + 'd1: begin
  1255.             t1_oe = 1;
  1256.             cp_we = 1;
  1257.             alu_oe = 1;
  1258.             alu_carry = 1;
  1259.             alu_opcode = `ADC;
  1260.  
  1261.             state_next = `fetch;
  1262.         end
  1263.  
  1264.         default: ;
  1265.     endcase
  1266. end
  1267.  
  1268. assign disp_state = state;
  1269.  
  1270. endmodule
  1271.  
Advertisement
Add Comment
Please, Sign In to add comment