/* CPEN 211 Lab 7: Simple RISC Machine */ /* Prayetnaa Kansakar & Danial Jaber */ /* fsm_controller.v */ //state encoding definitions `define SW 5 //`define Wait 5'b00000 `define Decode 5'b00001 `define GetA 5'b00010 `define GetB 5'b00011 `define ALU 5'b00100 `define WriteReg 5'b00101 `define WriteImm 5'b00110 `define MovRegA 5'b00111 `define MovRegB 5'b01000 `define MovRegC 5'b01001 `define RST 5'b01010 `define IF1 5'b01011 `define IF2 5'b01100 `define UpdatePC 5'b01101 `define Halt 5'b01110 `define AALU 5'b01111 `define Ld_Addr 5'b10000 `define Start_LDR 5'b10001 `define Start_STR 5'b10010 `define Mid_STR 5'b10011 `define LDR 5'b10100 `define STR 5'b10101 `define MNONE 2'b00 `define MREAD 2'b01 `define MWRITE 2'b10 module fsm_controller(clk, reset, opcode, op, write, loada, loadb, loadc, loads, asel, bsel, vsel, nsel, reset_pc, load_pc, mem_cmd, addr_sel, load_ir, load_addr); //i/o signals input clk, reset; input [2:0] opcode; input [1:0] op; output write, loada, loadb, loadc, loads, asel, bsel, reset_pc, load_pc, addr_sel, load_ir, load_addr; output [1:0] mem_cmd; output [3:0] vsel; output [2:0] nsel; wire [`SW-1:0] present_state, state_next_reset, state_next; reg [25:0] next; //clk controlled state DFF vDFFc #(`SW) STATE(.clk(clk), .in(state_next_reset), .out(present_state)); //reset mux assign state_next_reset = reset ? `RST : state_next; //combinational logic for FSM control always @(*) begin casex({present_state, opcode, op}) // begining states of FSM controller {`RST, 3'bxxx, 2'bxx} : next <= {`IF1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b1, 1'b1, `MNONE, 1'b0, 1'b0, 1'b0}; {`IF1, 3'bxxx, 2'bxx} : next <= {`IF2, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MREAD, 1'b1, 1'b0, 1'b0}; {`IF2, 3'bxxx, 2'bxx} : next <= {`UpdatePC, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MREAD, 1'b1, 1'b1, 1'b0}; {`UpdatePC, 3'bxxx, 2'bxx} : next <= {`Decode, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b1, `MNONE, 1'b0, 1'b0, 1'b0}; //decodes the type instruction using OPCODE (and OP for MOV) {`Decode, 3'b101, 2'bxx} : next <= {`GetA, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //ALU {`Decode, 3'b110, 2'b10} : next <= {`WriteImm, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //MOV {`Decode, 3'b110, 2'b00} : next <= {`MovRegA, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //MOV {`Decode, 3'b011, 2'bxx} : next <= {`GetA, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //LDR Memory {`Decode, 3'b100, 2'bxx} : next <= {`GetA, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //STR Memory {`Decode, 3'b111, 2'bxx} : next <= {`Halt, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //HALT Special {`GetA, 3'b011, 2'bxx} : next <= {`AALU, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b100, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //LDR: Get Rn {`GetA, 3'b100, 2'bxx} : next <= {`AALU, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b100, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //STR: Get Rn {`GetA, 3'b101, 2'bxx} : next <= {`GetB, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b100, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //ALU: Get Rn {`GetB, 3'bxxx, 2'b00} : next <= {`ALU, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b001, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //ADD: Get Rm {`GetB, 3'bxxx, 2'b10} : next <= {`ALU, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b001, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //AND: Get Rm {`GetB, 3'bxxx, 2'b11} : next <= {`ALU, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b001, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //MVN: Get Rm {`ALU, 3'bxxx, 2'bxx} : next <= {`WriteReg, 1'b0, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b1}; //ALU operation, lab 6 {`WriteReg, 3'bxxx, 2'bxx} : next <= {`IF1, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0001, 3'b010, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //place into Rd w/ datapath_out //new type of ALU operation sequence in lab 7, which uses sximm5 to shift Rn {`AALU, 3'bxxx, 2'bxx} : next <= {`Ld_Addr, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b1, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //bsel = 1, loadc = 1 //after finishing ALU operations, load_addr = 1 to enable data address register, addr_sel = 0 {`Ld_Addr, 3'b011, 2'bxx} : next <= {`Start_LDR, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b1}; {`Ld_Addr, 3'b100, 2'bxx} : next <= {`Start_STR, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b1}; //the start of LDR Memory instruction branch {`Start_LDR, 3'bxxx, 2'bxx} : next <= {`LDR, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MREAD, 1'b0, 1'b0, 1'b0}; //change m_cmd to MREAD //info on read_data, due to previous step //vsel = mdata, to write into Rd {`LDR, 3'bxxx, 2'bxx} : next <= {`IF1, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0010, 3'b010, 1'b0, 1'b0, `MREAD, 1'b0, 1'b0, 1'b0}; //the start of STR Memory instruction branch {`Start_STR, 3'bxxx, 2'bxx} : next <= {`Mid_STR, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b010, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; // loadb = 1 to {`Mid_STR, 3'bxxx, 2'bxx} : next <= {`STR, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; // asel = 1, loadc = 1 {`STR, 3'bxxx, 2'bxx} : next <= {`IF1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MWRITE, 1'b0, 1'b0, 1'b0}; //m_cmd to MWRITE //MOV immediate instuction {`WriteImm, 3'bxxx, 2'bxx} : next <= {`IF1, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0100, 3'b100, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //place into Rn //MOV register instruction {`MovRegA, 3'bxxx, 2'bxx} : next <= {`MovRegB, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b001, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //Loadb into Rm {`MovRegB, 3'bxxx, 2'bxx} : next <= {`MovRegC, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //put asel to one, loadc = 1 {`MovRegC, 3'bxxx, 2'bxx} : next <= {`IF1, 1'b1, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0, 4'b0001, 3'b010, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //place Load B into Rd //HALT Special instruction {`Halt, 3'bxxx, 2'bxx} : next <= {`Halt, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000, 1'b0, 1'b0, `MNONE, 1'b0, 1'b0, 1'b0}; //self loop to Halt, so that user must reset default : next <= {26{1'bx}}; endcase end assign {state_next, write, loada, loadb, loadc, loads, asel, bsel, vsel, nsel, reset_pc, load_pc, mem_cmd, addr_sel, load_ir, load_addr} = next; endmodule //D flip flop without load enable module vDFFc(clk, in, out); parameter n = 1; input clk; input [n-1:0] in; output reg [n-1:0] out; always @(posedge clk) out = in; endmodule