risc-processor-211 / CPEN Lab 6 / fsm_controller.v
fsm_controller.v
Raw
/* CPEN 211 Lab 6: Simple RISC Machine */
/* Prayetnaa Kansakar & Danial Jaber */
/* fsm_controller.v */

//state encoding definitions
`define SW 4
`define Wait     4'b0000
`define Decode   4'b0001
`define GetA     4'b0010
`define GetB     4'b0011
`define ALU      4'b0100
`define WriteReg 4'b0101
`define WriteImm 4'b0110
`define MovRegA  4'b0111
`define MovRegB  4'b1000
`define MovRegC 4'b1001

module fsm_controller(clk, reset, s, opcode, op, write,
    loada, loadb, loadc, loads, asel, bsel, vsel, nsel, w);
 
    //i/o signals
    input reset, s, clk;
    input [2:0] opcode;
    input [1:0] op;
    output write, loada, loadb, loadc, loads, asel, bsel, w; 
    output [3:0] vsel;
    output [2:0] nsel;

    wire [`SW-1:0] present_state, state_next_reset, state_next;
    reg [18: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 ? `Wait : state_next;

//combinational logic for fsm control
always @(*) begin

    casex({present_state, s, opcode, op})

    {`Wait, 1'b0, 3'bxxx, 2'bxx} : next <= {`Wait, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 4'b0000, 3'b000}; //Wait->Wait as long as s==0
    {`Wait, 1'b1, 3'bxxx, 2'bxx} : next <= {`Decode, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000}; //Wait->Decode when s==1; w==0

    {`Decode, 1'bx, 3'b101, 2'bxx} : next <= {`GetA, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000};
    {`Decode, 1'bx, 3'b110, 2'b10} : next <= {`WriteImm, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000};
    {`Decode, 1'bx, 3'b110, 2'b00} : next <= {`MovRegA, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000};

    {`GetA, 1'b0, 3'bxxx, 2'bxx} : next <= {`GetB, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b100}; //Get Rn
    {`GetB, 1'b0, 3'bxxx, 2'bxx} : next <= {`ALU, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b001}; //Get Rm
    {`ALU, 1'b0, 3'bxxx, 2'bxx} : next <= {`WriteReg, 1'b0, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b000}; //ALU operation
    {`WriteReg, 1'bx, 3'bxxx, 2'bxx} : next <= {`Wait, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0001, 3'b010}; //place into Rd

    {`WriteImm, 1'bx, 3'bxxx, 2'bxx} : next <= {`Wait, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0100, 3'b100}; //place into Rn

    {`MovRegA, 1'bx, 3'bxxx, 2'bxx} : next <= {`MovRegB, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 4'b0000, 3'b001}; //Load A into Rm
    {`MovRegB, 1'bx, 3'bxxx, 2'bxx} : next <= {`MovRegC, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 4'b0000, 3'b000}; //put asel to zero
    {`MovRegC, 1'bx, 3'bxxx, 2'bxx} : next <= {`Wait, 1'b1, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0, 1'b0, 4'b0001, 3'b010}; //place Load B into Rd
     
    default : next <= {19{1'bx}};
    endcase
end
assign {state_next, write, loada, loadb, loadc, loads, asel, bsel, w, vsel, nsel} = 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