Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `timescale 1ns / 1ps
- //////////////////////////////////////////////////////////////////////////////////
- // Company:
- // Engineer:
- //
- // Create Date: 20:14:45 11/26/2011
- // Design Name:
- // Module Name: uc
- // Project Name:
- // Target Devices:
- // Tool versions:
- // Description:
- //
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //////////////////////////////////////////////////////////////////////////////////
- module uc(
- clk,
- rst,
- ri,
- ind,
- regs_addr,
- regs_oe,
- regs_we,
- alu_oe,
- alu_carry,
- alu_opcode,
- ram_oe,
- ram_we,
- io_oe,
- io_we,
- cp_oe,
- cp_we,
- ind_sel,
- ind_oe,
- ind_we,
- am_oe,
- am_we,
- aie_oe,
- aie_we,
- t1_oe,
- t1_we,
- t2_oe,
- t2_we,
- ri_oe,
- ri_we,
- disp_state
- );
- parameter word_width = 16;
- parameter state_width = 16;
- `define ADC 0
- `define SBB1 1
- `define SBB2 2
- `define NOT 3
- `define AND 4
- `define OR 5
- `define XOR 6
- `define SHL 7
- `define SHR 8
- `define SAR 9
- `define RA 0
- `define RB 1
- `define RC 2
- `define IS 3
- `define XA 4
- `define XB 5
- `define BA 6
- `define BB 7
- input clk;
- input rst;
- input [word_width-1 : 0] ri;
- input [word_width-1 : 0] ind;
- output reg alu_oe;
- output reg alu_carry;
- output reg[3 : 0] alu_opcode;
- output reg ram_oe;
- output reg ram_we;
- output reg io_oe;
- output reg io_we;
- output reg[2 : 0] regs_addr;
- output reg regs_oe;
- output reg regs_we;
- output reg cp_oe;
- output reg cp_we;
- output reg ind_sel; // controls IND register input (0 = bus, 1 = alu flags)
- output reg ind_oe;
- output reg ind_we;
- output reg am_oe;
- output reg am_we;
- output reg aie_oe;
- output reg aie_we;
- output reg t1_oe;
- output reg t1_we;
- output reg t2_oe;
- output reg t2_we;
- output reg ri_oe; // controls RI register output which generates the offset for Jcond instructions
- output reg ri_we;
- output[state_width-1 : 0] disp_state;
- wire [0:6] cop;
- wire d;
- wire [0:1] mod;
- wire [0:2] rg;
- wire [0:2] rm;
- assign cop = {ri[0], ri[1], ri[2], ri[3], ri[4], ri[5], ri[6]};
- assign d = {ri[7]};
- assign mod = {ri[8], ri[9]};
- assign rg = {ri[10], ri[11], ri[12]};
- assign rm = {ri[13], ri[14], ri[15]};
- `define reset 'h00 // reset state
- `define fetch 'h10 // load instruction to instruction register
- `define decode 'h20 // analyze loaded instruction
- `define addr_sum 'h30 // computes address of the form [By+Xz] with y,z in {A, B}
- `define addr_reg 'h34 // computes address of the form [yz] with y in {X, B} and z in {A, B}
- `define load_src_reg 'h40 // load source operand from register
- `define load_src_mem 'h44 // load source operand from memory
- `define load_dst_reg 'h50 // load destination operand from register
- `define load_dst_mem 'h54 // load destination operand from memory
- `define exec_1op 'h60 // execute 1 operand instructions
- `define exec_2op 'h64 // execute 2 operand instructions
- `define transfer 'h68 // executa instructiuni de transfer
- `define store_reg 'h70 // store result to register
- `define store_mem 'h74 // store result to memory
- `define inc_cp 'h80 // increment program counter
- `define decrement_IS 'h90 // se implementeaza instructiunea PUSH
- `define increment_IS 'h100 // se implementeaza instructiunea POP
- `define addr_reg_deplasata 'h110 // implementare calcul adresa [XA/XB/BA/BB + Deplasament]
- `define addr_sum_deplasata 'h120 // implementare calcul adresa [BA + XA/XB / BB + XA/XB + Deplasament]
- `define load_operand_imediat 'h130 // memoreaza operandul imediat in T2
- `define skip_load_src 'h140 // se sare peste incarcarea registrului sursa
- `define skip_load_dst 'h150 // se sare peste incarcarea registrului destinatie
- `define jmp 'h160 // se implementeaza instructiunea JMP
- `define call 'h170 // se implementeaza instructiunea CALL
- `define jcond 'h180 // se implementeaza instructiunea JCOND
- `define skip_store 'h190 // to delete
- `define addr_autodecrement 'h200 // implenentare adresare cu autodecrementare
- `define addr_indirect 'h210 // implementare adresare indirecta
- `define ret 'h220 // se implementeaza instructiunea RET
- `define pushf 'h230 // se implementeaza instructiunea PUSHF
- `define popf 'h240 // se implementeaza instructiunea POPF
- `define addr_autoincrement 'h250 // implenentare adresare cu autoincrementare
- `define addr_2x_indirect 'h260 // implementere adresare dublu indirecta
- reg [state_width-1 : 0] state = `reset, state_next;
- reg [state_width-1 : 0] decoded_src, decoded_src_next; // stores decoded source operand load state
- reg [state_width-1 : 0] decoded_dst, decoded_dst_next; // stores decoded destination operand load state
- reg [state_width-1 : 0] decoded_exec, decoded_exec_next; // stores decoded execute state
- reg [state_width-1 : 0] decoded_store, decoded_store_next; // stores decoded store state
- reg decoded_d, decoded_d_next; // stores decoded direction bit
- // FSM - sequential part
- always @(posedge clk) begin
- state <= `reset;
- if(!rst) begin
- state <= state_next;
- if(state == `decode) begin
- decoded_src <= decoded_src_next;
- decoded_dst <= decoded_dst_next;
- decoded_exec <= decoded_exec_next;
- decoded_store <= decoded_store_next;
- decoded_d <= decoded_d_next;
- end
- end
- end
- // FSM - combinational part
- always @(*) begin
- state_next = `reset;
- decoded_src_next = `reset;
- decoded_dst_next = `reset;
- decoded_exec_next = `reset;
- decoded_store_next = `reset;
- decoded_d_next = 0;
- alu_oe = 0;
- alu_carry = 0;
- alu_opcode = 0;
- ram_oe = 0;
- ram_we = 0;
- io_oe = 0;
- io_we = 0;
- regs_addr = 0;
- regs_oe = 0;
- regs_we = 0;
- cp_oe = 0;
- cp_we = 0;
- ind_sel = 0;
- ind_oe = 0;
- ind_we = 0;
- am_oe = 0;
- am_we = 0;
- aie_oe = 0;
- aie_we = 0;
- t1_oe = 0;
- t1_we = 0;
- t2_oe = 0;
- t2_we = 0;
- ri_oe = 0;
- ri_we = 0;
- case(state)
- `reset: begin
- state_next = `fetch;
- end
- `fetch: begin
- cp_oe = 1;
- am_we = 1;
- state_next = `fetch + 1;
- end
- `fetch + 'd1: begin
- am_oe = 1;
- state_next = `fetch + 2;
- end
- `fetch + 'd2: begin
- ram_oe = 1;
- ri_we = 1;
- state_next = `decode;
- end
- //-----------------------------------------------------------------------//
- //Decode section
- `decode: begin
- // data transfer / control
- if(cop[0:3] == 4'b0000)
- begin
- if(cop[4:6] == 3'b000) // MOV
- begin
- decoded_d_next = d;
- decoded_exec_next = `transfer;
- decoded_dst_next = (mod == 2'b11) || (d == 1) ? `load_dst_reg : `load_dst_mem;
- decoded_src_next = (mod == 2'b11) || (d == 0) ? `load_src_reg : `load_src_mem;
- decoded_store_next = (mod == 2'b11) || (d == 1) ? `store_reg : `store_mem;
- end
- else if(cop[4:6] == 3'b010) // PUSH
- begin
- decoded_d_next = 0;
- decoded_exec_next = `decrement_IS;
- decoded_dst_next = (mod == 2'b11) ? `load_dst_reg : `load_dst_mem;
- decoded_src_next = `skip_load_src;
- decoded_store_next = `store_mem;
- end
- else if(cop[4:6] == 3'b011) // POP
- begin
- decoded_d_next = 0;
- decoded_exec_next = `increment_IS;
- decoded_dst_next = (mod != 2'b11) ? `skip_load_dst : `load_dst_reg;
- decoded_src_next = `skip_load_src;
- decoded_store_next = (mod == 2'b11) ? `store_reg : `store_mem;
- end
- else if(cop[4:6] == 3'b100) // CALL
- begin
- decoded_d_next = 0;
- decoded_exec_next = `call;
- decoded_dst_next = (mod != 2'b11) ? `skip_load_dst : `load_dst_reg;
- decoded_src_next = `skip_load_src;
- decoded_store_next = (mod == 2'b11) ? `store_reg : `store_mem;
- end
- else if(cop[4:6] == 3'b101) // JMP
- begin
- decoded_d_next = 0;
- decoded_exec_next = `jmp;
- decoded_dst_next = (mod != 2'b11) ? `skip_load_dst : `load_dst_reg;
- decoded_src_next = `skip_load_src;
- decoded_store_next = (mod == 2'b11) ? `store_reg : `store_mem;
- end
- end
- // MOV cu operand imediat
- else if(cop[0:3] == 3'b0010)
- begin
- decoded_d_next = 0;
- decoded_exec_next = `transfer;
- decoded_dst_next = mod == 2'b11 ? `load_dst_reg : `load_dst_mem;
- decoded_src_next = `load_operand_imediat;
- decoded_store_next = (mod == 2'b11) ? `store_reg : `store_mem;
- end
- // decode location of operands and operation
- else if(cop[0:3] == 4'b0001) // one operand instructions
- begin
- decoded_d_next = 0;
- decoded_dst_next = mod == 2'b11 ? `load_dst_reg : `load_dst_mem;
- decoded_src_next = decoded_dst_next;
- decoded_exec_next = `exec_1op;
- decoded_store_next = mod == 2'b11 ? `store_reg : `store_mem;
- end
- else if(cop[0:2] == 3'b010) // two operand instructions
- begin
- decoded_d_next = d;
- decoded_dst_next = (mod == 2'b11) || (d == 1) ? `load_dst_reg : `load_dst_mem;
- decoded_src_next = (mod == 2'b11) || (d == 0) ? `load_src_reg : `load_src_mem;
- decoded_exec_next = `exec_2op;
- decoded_store_next = !cop[3] ? `skip_store : ((mod == 2'b11) || (d == 1) ? `store_reg : `store_mem);
- end
- else if(cop[0:2] == 3'b011) // two operand instruction - adresare imediata
- begin
- decoded_d_next = 0;
- decoded_dst_next = (mod == 2'b11) ? `load_dst_reg : `load_dst_mem;
- decoded_src_next = `load_operand_imediat;
- decoded_exec_next = `exec_2op;
- decoded_store_next = (!cop[3]) ? `skip_store : ((mod == 2'b11) ? `store_reg : `store_mem);
- end
- else if(cop[0:3] == 4'b1001) // JCOND
- begin
- state_next = `jcond;
- end
- else if(cop[0:3] == 4'b1000)
- begin
- if(cop[4:6] == 3'b100) // RET
- begin
- state_next = `ret;
- end
- if(cop[4:6] == 3'b010) // PUSHF
- begin
- state_next = `pushf;
- end
- if(cop[4:6] == 3'b011) // POPF
- begin
- state_next = `popf;
- end
- end
- // decode address calculation mode
- if(cop[0] == 0)
- begin
- case(mod)
- 2'b00:
- begin
- state_next = rm[0] ? `addr_reg : `addr_sum;
- end
- 2'b01:
- begin
- if(rm[0] == 0)
- begin
- state_next = `addr_autoincrement;
- end
- else if(rm[1] == 0)
- begin
- state_next = `addr_autodecrement;
- end
- else if(rm[2] == 0)
- begin
- state_next = `addr_indirect;
- end
- else
- begin
- state_next = `addr_2x_indirect;
- end
- end
- 2'b10:
- begin
- state_next = rm[0] ? `addr_reg_deplasata : `addr_sum_deplasata;
- end
- 2'b11:
- begin
- state_next = decoded_src_next;
- end
- endcase
- end
- end
- //-----------------------------------------------------------------------//
- //Addresing of type [BA + XA/XB / BB + XA/XB + Deplasament]
- `addr_sum_deplasata:
- begin
- regs_addr = rm[1] ? `BB : `BA;
- regs_oe = 1;
- t1_we = 1;
- state_next = `addr_sum_deplasata + 1;
- end
- `addr_sum_deplasata + 'd1:
- begin
- regs_addr = rm[2] ? `XB : `XA;
- regs_oe = 1;
- t2_we = 1;
- state_next = `addr_sum_deplasata + 2;
- end
- // realizam suma dintre T1 si T2 pe care o introducem in T1
- // aceasta suma va reprezenta suma registrilor, la care urmeaza
- // sa adaugam deplasamentul
- `addr_sum_deplasata + 'd2:
- begin
- t1_oe = 1;
- t2_oe = 1;
- alu_carry = 0;
- alu_opcode = `ADC;
- alu_oe = 1;
- t1_we = 1;
- state_next = `addr_sum_deplasata + 3;
- end
- // se muta in T2 valoarea din registrul cp in scopul incrementarii ei
- `addr_sum_deplasata + 'd3:
- begin
- cp_oe = 1;
- t2_we = 1;
- state_next = `addr_sum_deplasata + 4;
- end
- // se incrementeaza cp
- `addr_sum_deplasata + 'd4:
- begin
- t2_oe = 1;
- alu_oe = 1;
- cp_we = 1;
- alu_carry = 1;
- alu_opcode = `ADC;
- state_next = `addr_sum_deplasata + 5;
- end
- // se scrie in am valoarea din cp in scopul obtinerii deplasamentului
- `addr_sum_deplasata + 'd5:
- begin
- cp_oe = 1;
- am_we = 1;
- state_next = `addr_sum_deplasata + 6;
- end
- `addr_sum_deplasata + 'd6:
- begin
- am_oe = 1;
- state_next = `addr_sum_deplasata + 7;
- end
- // in urm 2 stari se obtine deplasamentul din memorie, si se memoreaza in T2
- `addr_sum_deplasata + 'd7:
- begin
- ram_oe = 1;
- t2_we = 1;
- state_next = `addr_sum_deplasata + 8;
- end
- // prin suma dintre T1 si T2, se obtine valoarea adresei finale
- `addr_sum_deplasata + 'd8:
- begin
- t1_oe = 1;
- t2_oe = 1;
- alu_carry = 0;
- alu_opcode = `ADC;
- alu_oe = 1;
- if(decoded_d)
- t2_we = 1;
- else
- t1_we = 1;
- state_next = decoded_src;
- end
- //-----------------------------------------------------------------------//
- //Indirect addressing
- // pentru cazul adresarii indirecte, vom lua din memoria RAM operandul
- // incrementam CP, si il punem in AM pentru a citi urmatorul cuvant,
- // care reprezinta operandul
- `addr_indirect:
- begin
- cp_oe = 1;
- t1_we = 1;
- state_next = `addr_indirect + 1;
- end
- `addr_indirect + 'd1:
- begin
- t1_oe = 1;
- t2_oe = 0;
- alu_carry = 1;
- alu_opcode = `ADC;
- alu_oe = 1;
- am_we = 1;
- cp_we = 1;
- state_next = `addr_indirect + 2;
- end
- `addr_indirect + 'd2:
- begin
- am_oe = 1;
- state_next = `addr_indirect + 3;
- end
- `addr_indirect + 'd3:
- begin
- ram_oe = 1;
- if(decoded_d)
- t2_we = 1;
- else
- t1_we = 1;
- state_next = decoded_src;
- end
- //-----------------------------------------------------------------------//
- //Double indirect addressing
- // In cazul deplasarii dublu indirecte, operandul va fi luat tot din RAM
- // incrementam CP, il punem in AM pentru a citi urmatorul cuvant
- // urmatorul cuvant, il punem din nou in AM, pentru a obtine operandul
- // incrementare CP
- `addr_2x_indirect:
- begin
- t1_we = 1;
- cp_oe = 1;
- state_next = `addr_2x_indirect + 1;
- end
- `addr_2x_indirect + 'd1:
- begin
- t1_oe = 1;
- t2_oe = 0;
- alu_oe = 1;
- cp_we = 1;
- alu_carry = 1;
- alu_opcode = `ADC;
- state_next = `addr_2x_indirect + 2;
- end
- // introducem in AM CP+1 pentru a obtine urmatorul cuvant
- `addr_2x_indirect + 'd2:
- begin
- am_we = 1;
- cp_oe = 1;
- state_next = `addr_2x_indirect + 3;
- end
- `addr_2x_indirect + 'd3:
- begin
- am_oe = 1;
- state_next = `addr_2x_indirect + 4;
- end
- // cuvantul obtinut se introduce tot in AM, pentru a obtine operandul
- `addr_2x_indirect + 'd4:
- begin
- am_we = 1;
- ram_oe = 1;
- state_next = `addr_2x_indirect + 5;
- end
- `addr_2x_indirect + 'd5:
- begin
- am_oe = 1;
- state_next = `addr_2x_indirect + 6;
- end
- `addr_2x_indirect + 'd6:
- begin
- ram_oe = 1;
- if(decoded_d)
- t2_we = 1;
- else
- t1_we = 1;
- state_next = decoded_src;
- end
- //-----------------------------------------------------------------------//
- //Indirect addressing - reg sum - autodecrement
- // Adresa efectiva va fi adresa obtinuta prin insumarea
- // BB/BA + XA, unde XA este valoarea obtinuta dupa decrementare
- `addr_autodecrement:
- begin
- regs_addr = rm[2] ? `BB : `BA;
- regs_oe = 1;
- t1_we = 1;
- state_next = `addr_autodecrement + 1;
- end
- // se decrementeaza XA
- `addr_autodecrement + 'd1:
- begin
- regs_addr = `XA;
- regs_oe = 1;
- t2_we = 1;
- state_next = `addr_autodecrement + 2;
- end
- `addr_autodecrement + 'd2:
- begin
- t2_oe = 1;
- t1_oe = 0;
- regs_addr = `XA;
- regs_we = 1;
- alu_carry = 1;
- alu_opcode = `SBB2;
- alu_oe = 1;
- state_next = `addr_autodecrement + 3;
- end
- // urmarim sa realizam suma dintre XA decrementat si BB/BA
- `addr_autodecrement + 'd3:
- begin
- t2_we = 1;
- regs_addr = `XA;
- regs_oe = 1;
- state_next = `addr_autodecrement + 4;
- end
- `addr_autodecrement + 'd4:
- begin
- t1_oe = 1;
- t2_oe = 1;
- alu_opcode = `ADC;
- alu_oe = 1;
- if(decoded_d)
- t2_we = 1;
- else
- t1_we = 1;
- state_next = decoded_src;
- end
- `addr_reg: begin
- regs_addr = rm;
- regs_oe = 1;
- if(decoded_d)
- t2_we = 1;
- else
- t1_we = 1;
- state_next = decoded_src;
- end
- //-----------------------------------------------------------------------//
- //Indirect addressing - reg sum - autoincrement
- // Adresa efectiva va fi adresa obtinuta prin insumarea BA/BB + XA/XB
- // iar apoi XA/XB se incrementeaza
- // Initial vom realiza suma dintre registre, iar apoi vom incrementa XA si XB
- `addr_autoincrement:
- begin
- regs_addr = rm[1] ? `BB : `BA;
- regs_oe = 1;
- t1_we = 1;
- state_next = `addr_autoincrement + 1;
- end
- `addr_autoincrement + 'd1:
- begin
- regs_addr = rm[2] ? `XB : `XA;
- regs_oe = 1;
- t2_we = 1;
- state_next = `addr_autoincrement + 2;
- end
- // realizez suma dintre registrii
- `addr_autoincrement + 'd2:
- begin
- t1_oe = 1;
- t2_oe = 1;
- alu_opcode = `ADC;
- alu_oe = 1;
- if(decoded_d)
- t2_we = 1;
- else
- t1_we = 1;
- state_next = `addr_autoincrement + 3;
- end
- // se introduce XA sau XB in registrul ramas liber pentru a fi incrementat
- `addr_autoincrement + 'd3:
- begin
- regs_addr = rm[2] ? `XB : `XA;
- regs_oe = 1;
- if(decoded_d)
- t1_we = 1;
- else
- t2_we = 1;
- state_next = `addr_autoincrement + 4;
- end
- `addr_autoincrement + 'd4:
- begin
- regs_addr = rm[2] ? `XB : `XA;
- regs_we = 1;
- alu_carry = 1;
- alu_opcode = `ADC;
- alu_oe = 1;
- if(decoded_d)
- begin
- t1_oe = 1;
- t2_oe = 0;
- end
- else
- begin
- t1_oe = 0;
- t2_oe = 1;
- end
- state_next = decoded_src;
- end
- //-----------------------------------------------------------------------//
- //Memorarea operandului imediat
- // Se urmareste memorarea in T2 a operandului imediat, in scopul
- // implementarii operatiilor cu operand imediat
- // Urmarim prima data incrementarea CP, pentru a obtine operandul
- // de la adresa CP + 1
- `load_operand_imediat:
- begin
- cp_oe = 1;
- t2_we = 1;
- state_next = `load_operand_imediat + 1;
- end
- // Se obtine CP+1 si se trimite in CP si in AM
- `load_operand_imediat + 'd1:
- begin
- t2_oe = 1;
- alu_oe = 1;
- alu_carry = 1;
- alu_opcode = `ADC;
- cp_we = 1;
- am_we = 1;
- state_next = `load_operand_imediat + 2;
- end
- `load_operand_imediat + 'd2:
- begin
- am_oe = 1;
- state_next = `load_operand_imediat + 3;
- end
- // Obtinem din RAM valoarea operandului imediat, pe care o memoram in T2
- `load_operand_imediat + 'd3:
- begin
- ram_oe = 1;
- t2_we = 1;
- state_next = decoded_dst;
- end
- `load_src_reg: begin
- regs_addr = decoded_d ? rm : rg;
- regs_oe = 1;
- t2_we = 1;
- state_next = decoded_dst;
- end
- `load_src_mem: begin
- t1_oe = 0;
- t2_oe = 1;
- alu_opcode = `OR;
- alu_oe = 1;
- am_we = 1;
- state_next = `load_src_mem + 1;
- end
- `load_src_mem + 'd1: begin
- am_oe = 1;
- state_next = `load_src_mem + 2;
- end
- `load_src_mem + 'd2: begin
- ram_oe = 1;
- t2_we = 1;
- state_next = decoded_dst;
- end
- `load_dst_reg: begin
- regs_addr = decoded_d ? rg : rm;
- regs_oe = 1;
- t1_we = 1;
- state_next = decoded_exec;
- end
- `load_dst_mem: begin
- t1_oe = 1;
- t2_oe = 0;
- alu_opcode = `OR;
- alu_oe = 1;
- am_we = 1;
- state_next = `load_dst_mem + 1;
- end
- `load_dst_mem + 'd1: begin
- am_oe = 1;
- state_next = `load_dst_mem + 2;
- end
- `load_dst_mem + 'd2: begin
- ram_oe = 1;
- t1_we = 1;
- state_next = decoded_exec;
- end
- // atunci cand folosim doar T1 si utilizam un singur operand
- // sarim incarcarea T2
- `skip_load_src:
- begin
- state_next = decoded_dst;
- end
- // atunci cand folosim doar T2 si utilizam un singur operand
- // sarim incarcarea T1
- `skip_load_dst:
- begin
- state_next = decoded_exec;
- end
- `exec_1op: begin
- t1_oe = 1;
- case(cop[4:6])
- 3'b000: begin // INC
- alu_carry = 1;
- alu_opcode = `ADC;
- end
- 3'b001: begin // DEC
- alu_carry = 1;
- alu_opcode = `SBB1;
- end
- 3'b010: begin // NEG
- alu_carry = 0;
- alu_opcode = `SBB2;
- end
- 3'b011: begin // NOT
- alu_opcode = `NOT;
- end
- 3'b100: alu_opcode = `SHL; // SHL/SAL
- 3'b101: alu_opcode = `SHR; // SHR
- 3'b110: alu_opcode = `SAR; // SAR
- endcase
- alu_oe = 1;
- t1_we = 1;
- ind_sel = 1;
- ind_we = 1;
- state_next = decoded_store;
- end
- `exec_2op: begin
- t1_oe = 1;
- t2_oe = 1;
- case(cop[4:6])
- 3'b000: begin // ADD
- alu_carry = 0;
- alu_opcode = `ADC;
- end
- 3'b001: begin // ADC
- alu_carry = ind[0];
- alu_opcode = `ADC;
- end
- 3'b010: begin // SUB/CMP
- alu_carry = 0;
- alu_opcode = `SBB1;
- end
- 3'b011: begin // SBB
- alu_carry = ind[0];
- alu_opcode = `SBB1;
- end
- 3'b100: alu_opcode = `AND; // AND/TEST
- 3'b101: alu_opcode = `OR; // OR
- 3'b110: alu_opcode = `XOR; // XOR
- endcase
- alu_oe = 1;
- t1_we = 1;
- ind_sel = 1;
- ind_we = 1;
- state_next = decoded_store;
- end
- // Sarim peste etapa de stocare
- `skip_store:
- begin
- state_next = `inc_cp;
- end
- `store_reg: begin
- t1_oe = 1;
- t2_oe = 0;
- alu_opcode = `OR;
- alu_oe = 1;
- regs_addr = decoded_d ? rg : rm;
- regs_we = 1;
- state_next = `inc_cp;
- end
- `store_mem: begin
- t1_oe = 1;
- t2_oe = 0;
- alu_opcode = `OR;
- alu_oe = 1;
- am_oe = 1;
- ram_we = 1;
- state_next = `store_mem + 1;
- end
- `store_mem + 'd1: begin
- state_next = `inc_cp;
- end
- `inc_cp: begin
- cp_oe = 1;
- t1_we = 1;
- state_next = `inc_cp + 1;
- end
- `inc_cp + 'd1: begin
- t1_oe = 1;
- cp_we = 1;
- alu_oe = 1;
- alu_carry = 1;
- alu_opcode = `ADC;
- state_next = `fetch;
- end
- default: ;
- endcase
- end
- assign disp_state = state;
- endmodule
- `load_src: begin
- regs_addr = decoded_d ? rm : rg;
- regs_oe = 1;
- t2_we = 1;
- state_next = `load_dst;
- end
- `load_dst: begin
- regs_addr = decoded_d ? rg : rm;
- regs_oe = 1;
- t1_we = 1;
- state_next = decoded_exec;
- end
- `exec_1op: begin
- t1_oe = 1;
- case(cop[4:6])
- 3'b000: begin // INC
- alu_carry = 1;
- alu_opcode = `ADC;
- end
- 3'b001: begin // DEC
- alu_carry = 1;
- alu_opcode = `SBB1;
- end
- 3'b010: begin // NEG
- alu_carry = 0;
- alu_opcode = `SBB2;
- end
- 3'b011: begin // NOT
- alu_opcode = `NOT;
- end
- 3'b100: alu_opcode = `SHL; // SHL/SAL
- 3'b101: alu_opcode = `SHR; // SHR
- 3'b110: alu_opcode = `SAR; // SAR
- endcase
- alu_oe = 1;
- t1_we = 1;
- ind_sel = 1;
- ind_we = 1;
- state_next = decoded_store;
- end
- `exec_2op: begin
- t1_oe = 1;
- t2_oe = 1;
- case(cop[4:6])
- 3'b000: begin // ADD
- alu_carry = 0;
- alu_opcode = `ADC;
- end
- 3'b001: begin // ADC
- alu_carry = ind[0];
- alu_opcode = `ADC;
- end
- 3'b010: begin // SUB/CMP
- alu_carry = 0;
- alu_opcode = `SBB1;
- end
- 3'b011: begin // SBB
- alu_carry = ind[0];
- alu_opcode = `SBB1;
- end
- 3'b100: alu_opcode = `AND; // AND/TEST
- 3'b101: alu_opcode = `OR; // OR
- 3'b110: alu_opcode = `XOR; // XOR
- endcase
- alu_oe = 1;
- t1_we = 1;
- ind_sel = 1;
- ind_we = 1;
- state_next = decoded_store;
- end
- `store: begin
- t1_oe = 1;
- t2_oe = 0;
- alu_opcode = `OR;
- alu_oe = 1;
- regs_addr = decoded_d ? rg : rm;
- regs_we = 1;
- state_next = `inc_cp;
- end
- `inc_cp: begin
- cp_oe = 1;
- t1_we = 1;
- state_next = `inc_cp + 1;
- end
- `inc_cp + 'd1: begin
- t1_oe = 1;
- cp_we = 1;
- alu_oe = 1;
- alu_carry = 1;
- alu_opcode = `ADC;
- state_next = `fetch;
- end
- default: ;
- endcase
- end
- assign disp_state = state;
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment