Line 62... |
Line 62... |
|
|
input [15:0] read_mem_data,
|
input [15:0] read_mem_data,
|
input [15:0] perif_data,
|
input [15:0] perif_data,
|
input risc_clk,
|
input risc_clk,
|
input async_rst_b,
|
input async_rst_b,
|
|
input mem_req_ack, // Memory Bus available - data good
|
input xge, // XGATE Module Enable
|
input xge, // XGATE Module Enable
|
input xgfrz, // Stop XGATE in Freeze Mode
|
input xgfrz, // Stop XGATE in Freeze Mode
|
input xgdbg, // XGATE Debug Mode
|
input xgdbg, // XGATE Debug Mode
|
input xgss, // XGATE Single Step
|
input xgss, // XGATE Single Step
|
input [15:1] xgvbr, // XGATE vector Base Address Register
|
input [15:1] xgvbr, // XGATE vector Base Address Register
|
Line 94... |
Line 95... |
integer i, j; // Loop counters for decode of XGATE Interrupt Register
|
integer i, j; // Loop counters for decode of XGATE Interrupt Register
|
integer k; // Loop counter for Bit Field Insert decode
|
integer k; // Loop counter for Bit Field Insert decode
|
integer bfi, bfii, bfix; // Loop counter for Bit Field Insert function
|
integer bfi, bfii, bfix; // Loop counter for Bit Field Insert function
|
|
|
// State machine sequence
|
// State machine sequence
|
parameter [2:0] //synopsys enum state_info
|
parameter [3:0] //synopsys enum state_info
|
IDLE = 3'b000, // waiting for interrupt
|
IDLE = 4'b0000, // waiting for interrupt
|
CONT = 3'b001, // Instruction processing state, first state
|
CONT = 4'b0001, // Instruction processing state, first state
|
STALL = 3'b010, // Second step in 2 state instruction (Memory Read/Write)
|
DEBUG = 4'b0011, //
|
DEBUG = 3'b011, //
|
BOOT_1 = 4'b0100, //
|
BOOT_1 = 3'b100, //
|
BOOT_2 = 4'b0101, //
|
BOOT_2 = 3'b101, //
|
BOOT_3 = 4'b0110, //
|
BOOT_3 = 3'b110, //
|
S_STALL = 4'b0111, // Simple Stall while updating PC after change of flow
|
UNDEF5 = 3'b111; //
|
W_STALL = 4'b1000, // Stall while doing memory word read access
|
|
B_STALL = 4'b1001; // Stall while doing memory byte read access
|
|
|
|
|
// Semaphore states
|
// Semaphore states
|
parameter [1:0] NO_LOCK = 2'b00,
|
parameter [1:0] NO_LOCK = 2'b00,
|
RISC_LOCK = 2'b10,
|
RISC_LOCK = 2'b10,
|
HOST_LOCK = 2'b11;
|
HOST_LOCK = 2'b11;
|
|
|
|
|
reg [ 2:0] cpu_state;
|
reg [ 3:0] cpu_state;
|
reg [ 2:0] next_cpu_state; // Pseudo Register,
|
reg [ 3:0] next_cpu_state; // Pseudo Register,
|
reg load_next_inst; // Pseudo Register,
|
reg load_next_inst; // Pseudo Register,
|
reg [15:0] program_counter;
|
reg [15:0] program_counter;
|
reg [15:0] next_pc; // Pseudo Register,
|
reg [15:0] next_pc; // Pseudo Register,
|
reg [15:0] alu_result; // Pseudo Register,
|
reg [15:0] alu_result; // Pseudo Register,
|
reg [15:0] op_code;
|
reg [15:0] op_code;
|
Line 204... |
Line 206... |
wrt_sel_xgr4 = 1'b0;
|
wrt_sel_xgr4 = 1'b0;
|
wrt_sel_xgr5 = 1'b0;
|
wrt_sel_xgr5 = 1'b0;
|
wrt_sel_xgr6 = 1'b0;
|
wrt_sel_xgr6 = 1'b0;
|
wrt_sel_xgr7 = 1'b0;
|
wrt_sel_xgr7 = 1'b0;
|
case (wrt_reg_sel)
|
case (wrt_reg_sel)
|
3'b001 : wrt_sel_xgr1 = 1'b1;
|
3'b001 : wrt_sel_xgr1 = mem_req_ack;
|
3'b010 : wrt_sel_xgr2 = 1'b1;
|
3'b010 : wrt_sel_xgr2 = mem_req_ack;
|
3'b011 : wrt_sel_xgr3 = 1'b1;
|
3'b011 : wrt_sel_xgr3 = mem_req_ack;
|
3'b100 : wrt_sel_xgr4 = 1'b1;
|
3'b100 : wrt_sel_xgr4 = mem_req_ack;
|
3'b101 : wrt_sel_xgr5 = 1'b1;
|
3'b101 : wrt_sel_xgr5 = mem_req_ack;
|
3'b110 : wrt_sel_xgr6 = 1'b1;
|
3'b110 : wrt_sel_xgr6 = mem_req_ack;
|
3'b111 : wrt_sel_xgr7 = 1'b1;
|
3'b111 : wrt_sel_xgr7 = mem_req_ack;
|
endcase
|
endcase
|
end
|
end
|
|
|
// Decode register select for RS1 and RB
|
// Decode register select for RS1 and RB
|
always @*
|
always @*
|
Line 254... |
Line 256... |
bf_mux_mask[k] = 1'b1;
|
bf_mux_mask[k] = 1'b1;
|
k = k + 1;
|
k = k + 1;
|
end
|
end
|
end
|
end
|
|
|
|
|
// CPU State Register
|
// CPU State Register
|
always @(posedge risc_clk or negedge async_rst_b)
|
always @(posedge risc_clk or negedge async_rst_b)
|
if ( !async_rst_b )
|
if ( !async_rst_b )
|
cpu_state <= IDLE;
|
cpu_state <= IDLE;
|
else
|
else
|
cpu_state <= next_cpu_state;
|
cpu_state <= mem_req_ack ? next_cpu_state : cpu_state;
|
|
|
// CPU Instruction Register
|
// CPU Instruction Register
|
always @(posedge risc_clk or negedge async_rst_b)
|
always @(posedge risc_clk or negedge async_rst_b)
|
if ( !async_rst_b )
|
if ( !async_rst_b )
|
op_code <= 16'h0000;
|
op_code <= 16'h0000;
|
else
|
else
|
op_code <= load_next_inst ? read_mem_data : op_code;
|
op_code <= (load_next_inst && mem_req_ack) ? read_mem_data : op_code;
|
|
|
// Active Channel Latch
|
// Active Channel Latch
|
always @(posedge risc_clk or negedge async_rst_b)
|
always @(posedge risc_clk or negedge async_rst_b)
|
if ( !async_rst_b )
|
if ( !async_rst_b )
|
xgchid <= 7'b0;
|
xgchid <= 7'b0;
|
else
|
else
|
xgchid <= (cpu_state == IDLE) ? int_req : xgchid;
|
xgchid <= ((cpu_state == IDLE) && mem_req_ack) ? int_req : xgchid;
|
|
|
// CPU Read Data Buffer Register
|
// CPU Read Data Buffer Register
|
always @(posedge risc_clk or negedge async_rst_b)
|
always @(posedge risc_clk or negedge async_rst_b)
|
if ( !async_rst_b )
|
if ( !async_rst_b )
|
load_data <= 16'h0000;
|
load_data <= 16'h0000;
|
else
|
else
|
load_data <= (data_access && !data_write) ? read_mem_data : load_data;
|
load_data <= (data_access && !data_write && mem_req_ack) ? read_mem_data : load_data;
|
|
|
// Program Counter Register
|
// Program Counter Register
|
always @(posedge risc_clk or negedge async_rst_b)
|
always @(posedge risc_clk or negedge async_rst_b)
|
if ( !async_rst_b )
|
if ( !async_rst_b )
|
program_counter <= 16'h0000;
|
program_counter <= 16'h0000;
|
else
|
else
|
program_counter <= next_pc;
|
program_counter <= mem_req_ack ? next_pc : program_counter;
|
|
|
// ALU Flag Bits
|
// ALU Flag Bits
|
always @(posedge risc_clk or negedge async_rst_b)
|
always @(posedge risc_clk or negedge async_rst_b)
|
if ( !async_rst_b )
|
if ( !async_rst_b )
|
begin
|
begin
|
Line 301... |
Line 302... |
zero_flag <= 1'b0;
|
zero_flag <= 1'b0;
|
negative_flag <= 1'b0;
|
negative_flag <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
carry_flag <= write_xgccr ? perif_data[0] : next_carry;
|
carry_flag <= write_xgccr ? perif_data[0] : (mem_req_ack ? next_carry : carry_flag);
|
overflow_flag <= write_xgccr ? perif_data[1] : next_overflow;
|
overflow_flag <= write_xgccr ? perif_data[1] : (mem_req_ack ? next_overflow : overflow_flag);
|
zero_flag <= write_xgccr ? perif_data[2] : next_zero;
|
zero_flag <= write_xgccr ? perif_data[2] : (mem_req_ack ? next_zero : zero_flag);
|
negative_flag <= write_xgccr ? perif_data[3] : next_negative;
|
negative_flag <= write_xgccr ? perif_data[3] : (mem_req_ack ? next_negative : negative_flag);
|
end
|
end
|
|
|
// Interrupt Flag next value
|
// Interrupt Flag next value
|
always @*
|
always @*
|
begin
|
begin
|
Line 478... |
Line 479... |
next_cpu_state = xge ? DEBUG : IDLE;
|
next_cpu_state = xge ? DEBUG : IDLE;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
end
|
end
|
|
|
|
// Pause here while program counter change of flow or memory write access
|
|
// Load next instruction and increment PC
|
|
{S_STALL, 16'b????????????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Pause here for memory read word access
|
|
// Load next instruction and increment PC
|
|
{W_STALL, 16'b????????????????} :
|
|
begin
|
|
alu_result = load_data;
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Pause here for memory read byte access
|
|
// Load next instruction and increment PC
|
|
{B_STALL, 16'b????????????????} :
|
|
begin
|
|
alu_result = {8'h00, load_data[15:8]};
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
// Instruction Group -- Return to Scheduler and Others
|
// Instruction Group -- Return to Scheduler and Others
|
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
|
|
// Instruction = BRK, Op Code = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
// Instruction = BRK, Op Code = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
Line 599... |
Line 625... |
// PC + $0002 => RD; RD => PC
|
// PC + $0002 => RD; RD => PC
|
// Jumps to the address stored in RD and saves the return address in RD.
|
// Jumps to the address stored in RD and saves the return address in RD.
|
// Cycles - PP
|
// Cycles - PP
|
{CONT, 16'b00000???11110110} :
|
{CONT, 16'b00000???11110110} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
alu_result = program_counter;
|
alu_result = program_counter;
|
next_pc = rd_data;
|
next_pc = rd_data;
|
end
|
end
|
|
|
{STALL, 16'b00000???11110110} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = SIF RS, Op Code = 0 0 0 0 0 RS 1 1 1 1 0 1 1 1
|
// Instruction = SIF RS, Op Code = 0 0 0 0 0 RS 1 1 1 1 0 1 1 1
|
// Sets the Interrupt Flag associated with the channel id number
|
// Sets the Interrupt Flag associated with the channel id number
|
// contained in RS[6:0] is set. The content of RS[15:7] is ignored
|
// contained in RS[6:0] is set. The content of RS[15:7] is ignored
|
// Cycles - P
|
// Cycles - P
|
{CONT, 16'b00000???11110111} :
|
{CONT, 16'b00000???11110111} :
|
Line 1079... |
Line 1100... |
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0010000?????????} :
|
{CONT, 16'b0010000?????????} :
|
begin
|
begin
|
if (!carry_flag)
|
if (!carry_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0010000?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BCS REL9, Op Code = 0 0 1 0 0 0 1 REL9
|
// Instruction = BCS REL9, Op Code = 0 0 1 0 0 0 1 REL9
|
// Branch if Carry Set
|
// Branch if Carry Set
|
// If C = 1, then PC + $0002 + (REL9 << 1) => PC
|
// If C = 1, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0010001?????????} :
|
{CONT, 16'b0010001?????????} :
|
begin
|
begin
|
if (carry_flag)
|
if (carry_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0010001?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BNE REL9, Op Code = 0 0 1 0 0 1 0 REL9
|
// Instruction = BNE REL9, Op Code = 0 0 1 0 0 1 0 REL9
|
// Branch if Not Equal
|
// Branch if Not Equal
|
// If Z = 0, then PC + $0002 + (REL9 << 1) => PC
|
// If Z = 0, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0010010?????????} :
|
{CONT, 16'b0010010?????????} :
|
begin
|
begin
|
if (!zero_flag)
|
if (!zero_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0010010?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BEQ REL9, Op Code = 0 0 1 0 0 1 1 REL9
|
// Instruction = BEQ REL9, Op Code = 0 0 1 0 0 1 1 REL9
|
// Branch if Equal
|
// Branch if Equal
|
// If Z = 1, then PC + $0002 + (REL9 << 1) => PC
|
// If Z = 1, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0010011?????????} :
|
{CONT, 16'b0010011?????????} :
|
begin
|
begin
|
if (zero_flag)
|
if (zero_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0010011?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BPL REL9, Op Code = 0 0 1 0 1 0 0 REL9
|
// Instruction = BPL REL9, Op Code = 0 0 1 0 1 0 0 REL9
|
// Branch if Plus
|
// Branch if Plus
|
// If N = 0, then PC + $0002 + (REL9 << 1) => PC
|
// If N = 0, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0010100?????????} :
|
{CONT, 16'b0010100?????????} :
|
begin
|
begin
|
if (!negative_flag)
|
if (!negative_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0010100?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BMI REL9, Op Code = 0 0 1 0 1 0 1 REL9
|
// Instruction = BMI REL9, Op Code = 0 0 1 0 1 0 1 REL9
|
// Branch if Minus
|
// Branch if Minus
|
// If N = 1, then PC + $0002 + (REL9 << 1) => PC
|
// If N = 1, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0010101?????????} :
|
{CONT, 16'b0010101?????????} :
|
begin
|
begin
|
if (negative_flag)
|
if (negative_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0010101?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BVC REL9, Op Code = 0 0 1 0 1 1 0 REL9
|
// Instruction = BVC REL9, Op Code = 0 0 1 0 1 1 0 REL9
|
// Branch if Overflow Cleared
|
// Branch if Overflow Cleared
|
// If V = 0, then PC + $0002 + (REL9 << 1) => PC
|
// If V = 0, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0010110?????????} :
|
{CONT, 16'b0010110?????????} :
|
begin
|
begin
|
if (!overflow_flag)
|
if (!overflow_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0010110?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BVS REL9, Op Code = 0 0 1 0 1 1 1 REL9
|
// Instruction = BVS REL9, Op Code = 0 0 1 0 1 1 1 REL9
|
// Branch if Overflow Set
|
// Branch if Overflow Set
|
// If V = 1, then PC + $0002 + (REL9 << 1) => PC
|
// If V = 1, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0010111?????????} :
|
{CONT, 16'b0010111?????????} :
|
begin
|
begin
|
if (overflow_flag)
|
if (overflow_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0010111?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BHI REL9, Op Code = 0 0 1 1 0 0 0 REL9
|
// Instruction = BHI REL9, Op Code = 0 0 1 1 0 0 0 REL9
|
// Branch if Higher
|
// Branch if Higher
|
// If C | Z = 0, then PC + $0002 + (REL9 << 1) => PC
|
// If C | Z = 0, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0011000?????????} :
|
{CONT, 16'b0011000?????????} :
|
begin
|
begin
|
if (!(carry_flag || zero_flag))
|
if (!(carry_flag || zero_flag))
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0011000?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BLS REL9, Op Code = 0 0 1 1 0 0 1 REL9
|
// Instruction = BLS REL9, Op Code = 0 0 1 1 0 0 1 REL9
|
// Branch if Lower or Same
|
// Branch if Lower or Same
|
// If C | Z = 1, then PC + $0002 + (REL9 << 1) => PC
|
// If C | Z = 1, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0011001?????????} :
|
{CONT, 16'b0011001?????????} :
|
begin
|
begin
|
if (carry_flag || zero_flag)
|
if (carry_flag || zero_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0011001?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BGE REL9, Op Code = 0 0 1 1 0 1 0 REL9
|
// Instruction = BGE REL9, Op Code = 0 0 1 1 0 1 0 REL9
|
// Branch if Greater than or Equal to Zero
|
// Branch if Greater than or Equal to Zero
|
// If N ^ V = 0, then PC + $0002 + (REL9 << 1) => PC
|
// If N ^ V = 0, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0011010?????????} :
|
{CONT, 16'b0011010?????????} :
|
begin
|
begin
|
if (!(negative_flag ^ overflow_flag))
|
if (!(negative_flag ^ overflow_flag))
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0011010?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BLT REL9, Op Code = 0 0 1 1 0 1 1 REL9
|
// Instruction = BLT REL9, Op Code = 0 0 1 1 0 1 1 REL9
|
// Branch if Lower than Zero
|
// Branch if Lower than Zero
|
// If N ^ V = 1, then PC + $0002 + (REL9 << 1) => PC
|
// If N ^ V = 1, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0011011?????????} :
|
{CONT, 16'b0011011?????????} :
|
begin
|
begin
|
if (negative_flag ^ overflow_flag)
|
if (negative_flag ^ overflow_flag)
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0011011?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BGT REL9, Op Code = 0 0 1 1 1 0 0 REL9
|
// Instruction = BGT REL9, Op Code = 0 0 1 1 1 0 0 REL9
|
// Branch if Greater than Zero
|
// Branch if Greater than Zero
|
// If Z | (N ^ V) = 0, then PC + $0002 + (REL9 << 1) => PC
|
// If Z | (N ^ V) = 0, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0011100?????????} :
|
{CONT, 16'b0011100?????????} :
|
begin
|
begin
|
if (!(zero_flag || (negative_flag ^ overflow_flag)))
|
if (!(zero_flag || (negative_flag ^ overflow_flag)))
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0011100?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BLE REL9, Op Code = 0 0 1 1 1 0 1 REL9
|
// Instruction = BLE REL9, Op Code = 0 0 1 1 1 0 1 REL9
|
// Branch if Less or Equal to Zero
|
// Branch if Less or Equal to Zero
|
// If Z | (N ^ V) = 1, then PC + $0002 + (REL9 << 1) => PC
|
// If Z | (N ^ V) = 1, then PC + $0002 + (REL9 << 1) => PC
|
// Cycles - PP/P
|
// Cycles - PP/P
|
{CONT, 16'b0011101?????????} :
|
{CONT, 16'b0011101?????????} :
|
begin
|
begin
|
if (zero_flag || (negative_flag ^ overflow_flag))
|
if (zero_flag || (negative_flag ^ overflow_flag))
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
next_pc = program_counter + {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
end
|
end
|
end
|
end
|
|
|
{STALL, 16'b0011101?????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = BRA REL10, Op Code = 0 0 1 1 1 1 REL10
|
// Instruction = BRA REL10, Op Code = 0 0 1 1 1 1 REL10
|
// Branch Always, signed offset
|
// Branch Always, signed offset
|
// PC + $0002 + (REL10 << 1) => PC
|
// PC + $0002 + (REL10 << 1) => PC
|
// Cycles - PP
|
// Cycles - PP
|
{CONT, 16'b001111??????????} :
|
{CONT, 16'b001111??????????} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + {{5{op_code[9]}}, op_code[9:0], 1'b0};
|
next_pc = program_counter + {{5{op_code[9]}}, op_code[9:0], 1'b0};
|
end
|
end
|
|
|
{STALL, 16'b001111??????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
// Instruction Group -- Load and Store Instructions
|
// Instruction Group -- Load and Store Instructions
|
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
|
|
Line 1364... |
Line 1311... |
// M[RB, #OFFS5] => RD.L; $00 => RD.H
|
// M[RB, #OFFS5] => RD.L; $00 => RD.H
|
// RB field == RS1 field
|
// RB field == RS1 field
|
// Cycles - Pr
|
// Cycles - Pr
|
{CONT, 16'b01000???????????} :
|
{CONT, 16'b01000???????????} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = B_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_address = rs1_data + {11'b0, op_code[4:0]};
|
data_address = rs1_data + {11'b0, op_code[4:0]};
|
end
|
end
|
|
|
{STALL, 16'b01000???????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
alu_result = {8'h00, load_data[15:8]};
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Instruction = LDW RD, (RB, #OFFS5), Op Code = 0 1 0 0 1 RD RB OFFS5
|
// Instruction = LDW RD, (RB, #OFFS5), Op Code = 0 1 0 0 1 RD RB OFFS5
|
// Load Word from Memory, unsigned offset
|
// Load Word from Memory, unsigned offset
|
// M[RB, #OFFS5] => RD
|
// M[RB, #OFFS5] => RD
|
// RB field == RS1 field
|
// RB field == RS1 field
|
// Cycles - PR
|
// Cycles - PR
|
{CONT, 16'b01001???????????} :
|
{CONT, 16'b01001???????????} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = W_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_address = rs1_data + {11'b0, op_code[4:0]};
|
data_address = rs1_data + {11'b0, op_code[4:0]};
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01001???????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
alu_result = load_data;
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Instruction = STB RS, (RB, #OFFS5), Op Code = 0 1 0 1 0 RS RB OFFS5
|
// Instruction = STB RS, (RB, #OFFS5), Op Code = 0 1 0 1 0 RS RB OFFS5
|
// Store Byte to Memory, unsigned offset
|
// Store Byte to Memory, unsigned offset
|
// RS.L => M[RB, #OFFS5]
|
// RS.L => M[RB, #OFFS5]
|
// RS field == RD fieild, RB field == RS1 field
|
// RS field == RD fieild, RB field == RS1 field
|
// Cycles - Pw
|
// Cycles - Pw
|
{CONT, 16'b01010???????????} :
|
{CONT, 16'b01010???????????} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_write = 1'b1;
|
data_write = 1'b1;
|
data_address = rs1_data + {11'b0, op_code[4:0]};
|
data_address = rs1_data + {11'b0, op_code[4:0]};
|
end
|
end
|
|
|
{STALL, 16'b01010???????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
|
|
// Instruction = STW RS, (RB, #OFFS5), Op Code = 0 1 0 1 1 RS RB OFFS5
|
// Instruction = STW RS, (RB, #OFFS5), Op Code = 0 1 0 1 1 RS RB OFFS5
|
// Store Word to Memory, unsigned offset
|
// Store Word to Memory, unsigned offset
|
// RS => M[RB, #OFFS5]
|
// RS => M[RB, #OFFS5]
|
// RS field == RD fieild, RB field == RS1 field
|
// RS field == RD fieild, RB field == RS1 field
|
// Cycles - PW
|
// Cycles - PW
|
{CONT, 16'b01011???????????} :
|
{CONT, 16'b01011???????????} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_write = 1'b1;
|
data_write = 1'b1;
|
data_address = rs1_data + {11'b0, op_code[4:0]};
|
data_address = rs1_data + {11'b0, op_code[4:0]};
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01011???????????} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = LDB RD, (RB, RI), Op Code = 0 1 1 0 0 RD RB RI 0 0
|
// Instruction = LDB RD, (RB, RI), Op Code = 0 1 1 0 0 RD RB RI 0 0
|
// Load Byte from Memory
|
// Load Byte from Memory
|
// M[RB, RI] => RD.L; $00 => RD.H
|
// M[RB, RI] => RD.L; $00 => RD.H
|
// RB field == RS1 field, RI field == RS2 field
|
// RB field == RS1 field, RI field == RS2 field
|
// Cycles - Pr
|
// Cycles - Pr
|
{CONT, 16'b01100?????????00} :
|
{CONT, 16'b01100?????????00} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = B_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
end
|
end
|
|
|
{STALL, 16'b01100?????????00} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
alu_result = {8'h00, load_data[15:8]};
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Instruction = LDW RD, (RB, RI), Op Code = 0 1 1 0 1 RD RB RI 0 0
|
// Instruction = LDW RD, (RB, RI), Op Code = 0 1 1 0 1 RD RB RI 0 0
|
// Load Word from Memory
|
// Load Word from Memory
|
// M[RB, RI] => RD
|
// M[RB, RI] => RD
|
// RB field == RS1 field, RI field == RS2 field
|
// RB field == RS1 field, RI field == RS2 field
|
// Cycles - PR
|
// Cycles - PR
|
{CONT, 16'b01101?????????00} :
|
{CONT, 16'b01101?????????00} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = W_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01101?????????00} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
alu_result = load_data;
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Instruction = STB RS, (RB, RI), Op Code = 0 1 1 1 0 RS RB RI 0 0
|
// Instruction = STB RS, (RB, RI), Op Code = 0 1 1 1 0 RS RB RI 0 0
|
// RS.L => M[RB, RI]
|
// RS.L => M[RB, RI]
|
// Store Byte to Memory
|
// Store Byte to Memory
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// Cycles - Pw
|
// Cycles - Pw
|
{CONT, 16'b01110?????????00} :
|
{CONT, 16'b01110?????????00} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_write = 1'b1;
|
data_write = 1'b1;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
end
|
end
|
|
|
{STALL, 16'b01110?????????00} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = STW RS, (RB, RI), Op Code = 0 1 1 1 1 RS RB RI 0 0
|
// Instruction = STW RS, (RB, RI), Op Code = 0 1 1 1 1 RS RB RI 0 0
|
// Store Word to Memory
|
// Store Word to Memory
|
// RS => M[RB, RI]
|
// RS => M[RB, RI]
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// Cycles - PW
|
// Cycles - PW
|
{CONT, 16'b01111?????????00} :
|
{CONT, 16'b01111?????????00} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_write = 1'b1;
|
data_write = 1'b1;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01111?????????00} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = LDB RD, (RB, RI+), Op Code = 0 1 1 0 0 RD RB RI 0 1
|
// Instruction = LDB RD, (RB, RI+), Op Code = 0 1 1 0 0 RD RB RI 0 1
|
// Load Byte from Memory
|
// Load Byte from Memory
|
// M[RB, RI] => RD.L; $00 => RD.H; RI+1 => RI
|
// M[RB, RI] => RD.L; $00 => RD.H; RI+1 => RI
|
// If the same general purpose register is used as index (RI) and destination register (RD),
|
// If the same general purpose register is used as index (RI) and destination register (RD),
|
// the content of the register will not be incremented after the data move: M[RB, RI] => RD.L; $00 => RD.H
|
// the content of the register will not be incremented after the data move: M[RB, RI] => RD.L; $00 => RD.H
|
// RB field == RS1 field, RI field == RS2 field
|
// RB field == RS1 field, RI field == RS2 field
|
// Cycles - Pr
|
// Cycles - Pr
|
{CONT, 16'b01100?????????01} :
|
{CONT, 16'b01100?????????01} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = B_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
alu_result = rs2_data + 16'h0001;
|
alu_result = rs2_data + 16'h0001;
|
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01100?????????01} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
alu_result = {8'h00, load_data[15:8]};
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Instruction = LDW RD, (RB, RI+), Op Code = 0 1 1 0 1 RD RB RI 0 1
|
// Instruction = LDW RD, (RB, RI+), Op Code = 0 1 1 0 1 RD RB RI 0 1
|
// Load Word from Memory
|
// Load Word from Memory
|
// M[RB, RI] => RD; RI+2 => RI
|
// M[RB, RI] => RD; RI+2 => RI
|
// If the same general purpose register is used as index (RI) and destination register (RD),
|
// If the same general purpose register is used as index (RI) and destination register (RD),
|
// the content of the register will not be incremented after the data move: M[RB, RI] => RD
|
// the content of the register will not be incremented after the data move: M[RB, RI] => RD
|
// RB field == RS1 field, RI field == RS2 field
|
// RB field == RS1 field, RI field == RS2 field
|
// Cycles - PR
|
// Cycles - PR
|
{CONT, 16'b01101?????????01} :
|
{CONT, 16'b01101?????????01} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = W_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
Line 1579... |
Line 1465... |
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01101?????????01} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
alu_result = load_data;
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Instruction = STB RS, (RB, RI+), Op Code = 0 1 1 1 0 RS RB RI 0 1
|
// Instruction = STB RS, (RB, RI+), Op Code = 0 1 1 1 0 RS RB RI 0 1
|
// Store Byte to Memory
|
// Store Byte to Memory
|
// RS.L => M[RB, RI]; RI+1 => RI
|
// RS.L => M[RB, RI]; RI+1 => RI
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// Cycles - Pw
|
// Cycles - Pw
|
{CONT, 16'b01110?????????01} :
|
{CONT, 16'b01110?????????01} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_write = 1'b1;
|
data_write = 1'b1;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
Line 1606... |
Line 1484... |
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01110?????????01} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = STW RS, (RB, RI+), Op Code = 0 1 1 1 1 RS RB RI 0 1
|
// Instruction = STW RS, (RB, RI+), Op Code = 0 1 1 1 1 RS RB RI 0 1
|
// Store Word to Memory
|
// Store Word to Memory
|
// RS => M[RB, RI]; RI+2 => RI
|
// RS => M[RB, RI]; RI+2 => RI
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// Cycles - PW
|
// Cycles - PW
|
{CONT, 16'b01111?????????01} :
|
{CONT, 16'b01111?????????01} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_write = 1'b1;
|
data_write = 1'b1;
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
Line 1631... |
Line 1504... |
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01111?????????01} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = LDB RD, (RB, -RI), Op Code = 0 1 1 0 0 RD RB RI 1 0
|
// Instruction = LDB RD, (RB, -RI), Op Code = 0 1 1 0 0 RD RB RI 1 0
|
// Load Byte from Memory
|
// Load Byte from Memory
|
// RI-1 => RI; M[RS, RI] => RD.L; $00 => RD.H
|
// RI-1 => RI; M[RS, RI] => RD.L; $00 => RD.H
|
// RB field == RS1 field, RI field == RS2 field
|
// RB field == RS1 field, RI field == RS2 field
|
// Cycles - Pr
|
// Cycles - Pr
|
{CONT, 16'b01100?????????10} :
|
{CONT, 16'b01100?????????10} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = B_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
alu_result = rs2_data + 16'hffff;
|
alu_result = rs2_data + 16'hffff;
|
data_address = rs1_data + alu_result;
|
data_address = rs1_data + alu_result;
|
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01100?????????10} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
alu_result = {8'h00, load_data[15:8]};
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Instruction = LDW RD, (RB, -RI), Op Code = 0 1 1 0 1 RD RB RI 1 0
|
// Instruction = LDW RD, (RB, -RI), Op Code = 0 1 1 0 1 RD RB RI 1 0
|
// Load Word from Memory
|
// Load Word from Memory
|
// RI-2 => RI; M[RS, RI] => RD
|
// RI-2 => RI; M[RS, RI] => RD
|
// RB field == RS1 field, RI field == RS2 field
|
// RB field == RS1 field, RI field == RS2 field
|
// Cycles - PR
|
// Cycles - PR
|
{CONT, 16'b01101?????????10} :
|
{CONT, 16'b01101?????????10} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = W_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
alu_result = rs2_data + 16'hfffe;
|
alu_result = rs2_data + 16'hfffe;
|
data_address = rs1_data + alu_result;
|
data_address = rs1_data + alu_result;
|
Line 1681... |
Line 1541... |
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01101?????????10} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
alu_result = load_data;
|
|
ena_rd_low_byte = 1'b1;
|
|
ena_rd_high_byte = 1'b1;
|
|
end
|
|
|
|
// Instruction = STB RS, (RB, -RI), Op Code = 0 1 1 1 0 RS RB RI 1 0
|
// Instruction = STB RS, (RB, -RI), Op Code = 0 1 1 1 0 RS RB RI 1 0
|
// Store Byte to Memory
|
// Store Byte to Memory
|
// RI-1 => RI; RS.L => M[RB, RI]
|
// RI-1 => RI; RS.L => M[RB, RI]
|
// If the same general purpose register is used as index (RI) and source register (RS),
|
// If the same general purpose register is used as index (RI) and source register (RS),
|
// the unmodified content of the source register is written to the memory: RS.L => M[RB, RS-1]; RS-1 => RS
|
// the unmodified content of the source register is written to the memory: RS.L => M[RB, RS-1]; RS-1 => RS
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// Cycles - Pw
|
// Cycles - Pw
|
{CONT, 16'b01110?????????10} :
|
{CONT, 16'b01110?????????10} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_write = 1'b1;
|
data_write = 1'b1;
|
alu_result = rs2_data + 16'hffff;
|
alu_result = rs2_data + 16'hffff;
|
Line 1710... |
Line 1562... |
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01110?????????10} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// Instruction = STW RS, (RB, -RI), Op Code = 0 1 1 1 1 RS RB RI 1 0
|
// Instruction = STW RS, (RB, -RI), Op Code = 0 1 1 1 1 RS RB RI 1 0
|
// Store Word to Memory
|
// Store Word to Memory
|
// RI-2 => RI; RS => M[RB, RI]
|
// RI-2 => RI; RS => M[RB, RI]
|
// If the same general purpose register is used as index (RI) and source register (RS),
|
// If the same general purpose register is used as index (RI) and source register (RS),
|
// the unmodified content of the source register is written to the memory: RS => M[RB, RS-2]; RS-2 => RS
|
// the unmodified content of the source register is written to the memory: RS => M[RB, RS-2]; RS-2 => RS
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
|
// Cycles - PW
|
// Cycles - PW
|
{CONT, 16'b01111?????????10} :
|
{CONT, 16'b01111?????????10} :
|
begin
|
begin
|
next_cpu_state = STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_write = 1'b1;
|
data_write = 1'b1;
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
Line 1737... |
Line 1584... |
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_low_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
ena_rd_high_byte = 1'b1;
|
end
|
end
|
|
|
{STALL, 16'b01111?????????10} :
|
|
begin
|
|
next_cpu_state = CONT;
|
|
end
|
|
|
|
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
// Instruction Group -- Bit Field Instructions
|
// Instruction Group -- Bit Field Instructions
|
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
|
|
// Instruction = BFEXT RD, RS1, RS2, Op Code = 0 1 1 0 0 RD RS1 RS2 1 1
|
// Instruction = BFEXT RD, RS1, RS2, Op Code = 0 1 1 0 0 RD RS1 RS2 1 1
|
Line 2072... |
Line 1914... |
4'h7 : semap_risc_bit = 8'b1000_0000;
|
4'h7 : semap_risc_bit = 8'b1000_0000;
|
endcase
|
endcase
|
|
|
assign semaph_stat = |risc_semap;
|
assign semaph_stat = |risc_semap;
|
|
|
|
// A "generate" statment would be good here but it's not supported in iverilog
|
// Semaphore Bit
|
// Semaphore Bit
|
semaphore_bit semaphore_0(
|
semaphore_bit semaphore_0(
|
// outputs
|
// outputs
|
.host_status( host_semap[0] ),
|
.host_status( host_semap[0] ),
|
.risc_status( risc_semap[0] ),
|
.risc_status( risc_semap[0] ),
|