Line 47... |
Line 47... |
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
|
|
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
|
|
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, address, control, data_out, alu_opcode, alu_a, alu_enable);
|
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, address, control, data_out, alu_opcode, alu_a, alu_enable);
|
parameter DATA_SIZE = 4'd8;
|
parameter DATA_SIZE = 4'h8;
|
parameter ADDR_SIZE = 4'd13;
|
parameter ADDR_SIZE = 4'hd;
|
|
|
|
localparam DATA_SIZE_ = DATA_SIZE - 1'b1;
|
|
localparam ADDR_SIZE_ = ADDR_SIZE - 1'b1;
|
|
|
input clk;
|
input clk;
|
input reset_n;
|
input reset_n;
|
input [DATA_SIZE-1:0] alu_result;
|
input [DATA_SIZE_:0] alu_result;
|
input [DATA_SIZE-1:0] alu_status;
|
input [DATA_SIZE_:0] alu_status;
|
input [DATA_SIZE-1:0] data_in;
|
input [DATA_SIZE_:0] data_in;
|
output reg [ADDR_SIZE-1:0] address;
|
output reg [ADDR_SIZE_:0] address;
|
output reg control; // one bit is enough? read = 0, write = 1
|
output reg control; // one bit is enough? read = 0, write = 1
|
output reg [DATA_SIZE-1:0] data_out;
|
output reg [DATA_SIZE_:0] data_out;
|
output reg [DATA_SIZE-1:0] alu_opcode;
|
output reg [DATA_SIZE_:0] alu_opcode;
|
output reg [DATA_SIZE-1:0] alu_a;
|
output reg [DATA_SIZE_:0] alu_a;
|
output reg alu_enable;
|
output reg alu_enable;
|
|
|
|
|
// FSM states
|
// FSM states
|
localparam RESET = 4'b1111;
|
localparam RESET = 4'b1111;
|
Line 81... |
Line 84... |
|
|
// control signals
|
// control signals
|
localparam MEM_READ = 1'b0;
|
localparam MEM_READ = 1'b0;
|
localparam MEM_WRITE = 1'b1;
|
localparam MEM_WRITE = 1'b1;
|
|
|
reg [ADDR_SIZE-1:0] pc; // program counter
|
reg [ADDR_SIZE_:0] pc; // program counter
|
reg [DATA_SIZE-1:0] sp; // stack pointer
|
reg [DATA_SIZE_:0] sp; // stack pointer
|
reg [DATA_SIZE-1:0] ir; // instruction register
|
reg [DATA_SIZE_:0] ir; // instruction register
|
reg [ADDR_SIZE:0] temp_addr; // temporary address
|
reg [ADDR_SIZE_:0] temp_addr; // temporary address
|
reg [DATA_SIZE-1:0] temp_data; // temporary data
|
reg [DATA_SIZE_:0] temp_data; // temporary data
|
|
|
reg [3:0] state, next_state; // current and next state registers
|
reg [3:0] state, next_state; // current and next state registers
|
// TODO: not sure if this will be 4 bits wide. as of march 9th this was 4bit wide.
|
// TODO: not sure if this will be 4 bits wide. as of march 9th this was 4bit wide.
|
|
|
// wiring that simplifies the FSM logic
|
// wiring that simplifies the FSM logic
|
Line 107... |
Line 110... |
reg read;
|
reg read;
|
reg read_modify_write;
|
reg read_modify_write;
|
reg write;
|
reg write;
|
reg jump;
|
reg jump;
|
|
|
wire [ADDR_SIZE-1:0] next_pc;
|
wire [ADDR_SIZE_:0] next_pc;
|
assign next_pc = pc + 13'b0000000000001;
|
assign next_pc = pc + 13'b0000000000001;
|
|
|
always @ (posedge clk or negedge reset_n) begin // sequencial always block
|
always @ (posedge clk or negedge reset_n) begin // sequencial always block
|
if (reset_n == 1'b0) begin
|
if (reset_n == 1'b0) begin
|
// all registers must assume default values
|
// all registers must assume default values
|
pc <= 0; // TODO: this is written somewhere. something about a reset vector. must be checked.
|
pc <= 0; // TODO: this is written somewhere. something about a reset vector. must be checked.
|
sp <= 0; // TODO: the default is not 0. maybe $0100 or something like that. must be checked.
|
sp <= 0; // TODO: the default is not 0. maybe $0100 or something like that. must be checked.
|
ir <= 0;
|
ir <= 8'h00;
|
temp_addr <= 0;
|
temp_addr <= 0;
|
temp_data <= 0;
|
temp_data <= 8'h00;
|
state <= RESET;
|
state <= RESET;
|
// registered outputs also receive default values
|
// registered outputs also receive default values
|
address <= 0;
|
address <= 0;
|
control <= 0; // check if these 2 shouldnt be on the other always block along with the address
|
control <= MEM_READ;
|
data_out <= 0;
|
data_out <= 8'h00;
|
end
|
end
|
else begin
|
else begin
|
state <= next_state;
|
state <= next_state;
|
control <= MEM_READ;
|
control <= MEM_READ;
|
data_out = 8'hZ;
|
data_out <= 8'h00;
|
case (state)
|
case (state)
|
RESET: begin
|
RESET: begin
|
// The processor was reset
|
// The processor was reset
|
|
$write("under reset");
|
end
|
end
|
FETCH_OP: begin // this state is the simplest one. it is a simple fetch that must be done when the cpu was reset or
|
FETCH_OP: begin // this state is the simplest one. it is a simple fetch that must be done when the cpu was reset or
|
// the last cycle was a memory write.
|
// the last cycle was a memory write.
|
pc <= next_pc;
|
pc <= next_pc;
|
address <= next_pc;
|
address <= next_pc;
|
Line 227... |
Line 231... |
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
always @ (*) begin // this is the next_state logic and the output logic always block
|
always @ (*) begin // this is the next_state logic and the output logic always block
|
//control = MEM_READ;
|
|
//data_out = 8'h00;
|
|
|
|
alu_opcode = 8'h00;
|
alu_opcode = 8'h00;
|
alu_a = 8'h00;
|
alu_a = 8'h00;
|
alu_enable = 1'b0;
|
alu_enable = 1'b0;
|
//address = pc;
|
|
|
|
next_state = RESET; // this prevents the latch
|
next_state = RESET; // this prevents the latch
|
|
|
case (state)
|
case (state)
|
RESET: begin
|
RESET: begin
|
next_state = FETCH_OP;
|
next_state = FETCH_OP;
|
end
|
end
|
FETCH_OP: begin
|
FETCH_OP: begin
|
next_state = FETCH_LOW;
|
next_state = FETCH_LOW;
|
end
|
end
|
FETCH_OP_CALC: begin
|
//FETCH_OP_CALC: begin // so far no addressing mode required the use of this state
|
next_state = FETCH_LOW;
|
// next_state = FETCH_LOW;
|
alu_opcode = ir;
|
// alu_opcode = ir;
|
alu_enable = 1'b1;
|
// alu_enable = 1'b1;
|
|
//end
|
end
|
|
FETCH_OP_CALC_PARAM: begin
|
FETCH_OP_CALC_PARAM: begin
|
next_state = FETCH_LOW;
|
next_state = FETCH_LOW;
|
alu_opcode = ir;
|
alu_opcode = ir;
|
alu_enable = 1'b1;
|
alu_enable = 1'b1;
|
alu_a = temp_data;
|
alu_a = temp_data;
|
Line 284... |
Line 283... |
end
|
end
|
|
|
if (write) begin
|
if (write) begin
|
alu_opcode = ir;
|
alu_opcode = ir;
|
alu_enable = 1'b1;
|
alu_enable = 1'b1;
|
alu_a = 8'hzz;
|
alu_a = 8'h00;
|
end
|
end
|
|
|
|
|
end
|
end
|
FETCH_HIGH: begin
|
FETCH_HIGH: begin
|