Line 108... |
Line 108... |
// State machine sequence
|
// State machine sequence
|
parameter [3:0] //synopsys enum state_info
|
parameter [3:0] //synopsys enum state_info
|
IDLE = 4'b0000, // waiting for interrupt
|
IDLE = 4'b0000, // waiting for interrupt
|
CONT = 4'b0001, // Instruction processing state, first state
|
CONT = 4'b0001, // Instruction processing state, first state
|
S_STALL = 4'b0010, // Simple Stall while updating PC after change of flow
|
S_STALL = 4'b0010, // Simple Stall while updating PC after change of flow
|
W_STALL = 4'b0011, // Stall while doing memory word read access
|
W_STORE = 4'b1101, // Stall while doing memory word write access
|
B_STALL = 4'b0100, // Stall while doing memory byte read access
|
W_LOAD = 4'b0011, // Stall while doing memory word read access
|
|
B_LOAD = 4'b0100, // Stall while doing memory byte read access
|
BREAK = 4'b0101, // Stop in this state after BRK instruction
|
BREAK = 4'b0101, // Stop in this state after BRK instruction
|
BREAK_2 = 4'b0110, // Advance PC after Single Step command
|
BREAK_2 = 4'b0110, // Advance PC after Single Step command
|
LD_INST = 4'b0111, // Load Instruction in Debug mode
|
LD_INST = 4'b0111, // Load Instruction in Debug mode
|
DEBUG = 4'b1000, // Stop in this state while waiting for debug commands
|
DEBUG = 4'b1000, // Stop in this state while waiting for debug commands
|
BOOT_1 = 4'b1001, //
|
BOOT_1 = 4'b1001, //
|
Line 130... |
Line 131... |
|
|
reg [ 3:0] cpu_state; // State register for instruction processing
|
reg [ 3:0] cpu_state; // State register for instruction processing
|
reg [ 3: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; // Program Counter register
|
reg [15:0] program_counter; // Program Counter register
|
reg [15:0] next_pc; // Pseudo Register,
|
wire [15:0] pc_sum; // Program Counter Adder
|
|
reg [15:0] pc_incr_mux; // Pseudo Register, mux to select the Program Counter Increment value
|
|
reg [15:0] next_pc; // Pseudo Register
|
|
wire [15:0] jump_offset; // Address offset to be added to pc on conditional branch instruction
|
|
wire [15:0] bra_offset; // Address offset to be added to pc on branch always instruction
|
reg [15:0] alu_result; // Pseudo Register,
|
reg [15:0] alu_result; // Pseudo Register,
|
reg [15:0] op_code; // Register for instruction being executed
|
reg [15:0] op_code; // Register for instruction being executed
|
reg ena_rd_low_byte; // Pseudo Register,
|
reg ena_rd_low_byte; // Pseudo Register,
|
reg ena_rd_high_byte; // Pseudo Register,
|
reg ena_rd_high_byte; // Pseudo Register,
|
|
|
Line 202... |
Line 207... |
// Debug states for change CHID
|
// Debug states for change CHID
|
parameter [1:0] CHID_IDLE = 2'b00,
|
parameter [1:0] CHID_IDLE = 2'b00,
|
CHID_TEST = 2'b10,
|
CHID_TEST = 2'b10,
|
CHID_WAIT = 2'b11;
|
CHID_WAIT = 2'b11;
|
|
|
|
assign jump_offset = {{6{op_code[8]}}, op_code[8:0], 1'b0};
|
|
assign bra_offset = {{5{op_code[9]}}, op_code[9:0], 1'b0};
|
|
assign pc_sum = program_counter + pc_incr_mux;
|
|
|
assign xgate_address = data_access ? data_address : program_counter;
|
assign xgate_address = data_access ? data_address : program_counter;
|
|
|
assign mem_access = data_access || load_next_inst;
|
assign mem_access = data_access || load_next_inst;
|
|
|
Line 502... |
Line 510... |
ena_rd_low_byte = 1'b0;
|
ena_rd_low_byte = 1'b0;
|
ena_rd_high_byte = 1'b0;
|
ena_rd_high_byte = 1'b0;
|
|
|
next_cpu_state = debug_active ? LD_INST : CONT;
|
next_cpu_state = debug_active ? LD_INST : CONT;
|
load_next_inst = 1'b1;
|
load_next_inst = 1'b1;
|
// next_pc = debug_active ? program_counter : program_counter + 16'h0002;
|
pc_incr_mux = 16'h0002; // Verilog Instruction order dependent
|
next_pc = program_counter + 16'h0002;
|
next_pc = pc_sum; // ""
|
|
|
next_zero = zero_flag;
|
next_zero = zero_flag;
|
next_negative = negative_flag;
|
next_negative = negative_flag;
|
next_carry = carry_flag;
|
next_carry = carry_flag;
|
next_overflow = overflow_flag;
|
next_overflow = overflow_flag;
|
Line 537... |
Line 545... |
casez ({cpu_state, op_code})
|
casez ({cpu_state, op_code})
|
|
|
{IDLE, 16'b????????????????} :
|
{IDLE, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = start_thread ? BOOT_1 : IDLE;
|
next_cpu_state = start_thread ? BOOT_1 : IDLE;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
end
|
end
|
|
|
{CHG_CHID, 16'b????????????????} :
|
{CHG_CHID, 16'b????????????????} :
|
begin
|
begin
|
Line 550... |
Line 559... |
else if (single_step || !debug_active)
|
else if (single_step || !debug_active)
|
next_cpu_state = BOOT_1;
|
next_cpu_state = BOOT_1;
|
else
|
else
|
next_cpu_state = CHG_CHID;
|
next_cpu_state = CHG_CHID;
|
|
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
end
|
end
|
|
|
// Output RAM address for Program Counter
|
// Output RAM address for Program Counter
|
{BOOT_1, 16'b????????????????} :
|
{BOOT_1, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = BOOT_2;
|
next_cpu_state = BOOT_2;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
data_address = {xgvbr, 1'b0} + {7'b0, xgchid, 2'b0};
|
data_address = {xgvbr, 1'b0} + {7'b0, xgchid, 2'b0};
|
end
|
end
|
Line 583... |
Line 594... |
// Load first instruction to op_code register
|
// Load first instruction to op_code register
|
// Increment Program Counter
|
// Increment Program Counter
|
{BOOT_3, 16'b????????????????} :
|
{BOOT_3, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = CONT;
|
next_cpu_state = CONT;
|
load_next_inst = 1'b1;
|
|
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 = load_data;
|
alu_result = load_data;
|
end
|
end
|
|
|
Line 599... |
Line 609... |
next_cpu_state = BREAK_2;
|
next_cpu_state = BREAK_2;
|
else if (chid_goto_idle)
|
else if (chid_goto_idle)
|
next_cpu_state = CHG_CHID;
|
next_cpu_state = CHG_CHID;
|
else
|
else
|
next_cpu_state = BREAK;
|
next_cpu_state = BREAK;
|
// next_cpu_state = (xge && !chid_goto_idle) ?
|
|
// ((single_step || !debug_active) ?
|
|
// BREAK_2 : BREAK) : IDLE;
|
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
end
|
end
|
|
|
{BREAK_2, 16'b????????????????} :
|
{BREAK_2, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = LD_INST;
|
next_cpu_state = LD_INST;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter + 2;
|
|
end
|
end
|
|
|
{LD_INST, 16'b????????????????} :
|
{LD_INST, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = DEBUG;
|
next_cpu_state = DEBUG;
|
load_next_inst = 1'b1;
|
pc_incr_mux = 16'h0000;
|
next_pc = program_counter;
|
next_pc = pc_sum;
|
end
|
end
|
|
|
{DEBUG, 16'b????????????????} :
|
{DEBUG, 16'b????????????????} :
|
begin
|
begin
|
if (!xge)
|
if (!xge)
|
Line 633... |
Line 640... |
else if (chid_goto_idle)
|
else if (chid_goto_idle)
|
next_cpu_state = CHG_CHID;
|
next_cpu_state = CHG_CHID;
|
else
|
else
|
next_cpu_state = DEBUG;
|
next_cpu_state = DEBUG;
|
|
|
// next_cpu_state = (xge && !chid_goto_idle) ?
|
|
// ((single_step || !debug_active) ?
|
|
// CONT : (cmd_change_pc ? LD_INST : DEBUG)) : IDLE;
|
|
load_next_inst = cmd_change_pc;
|
load_next_inst = cmd_change_pc;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
end
|
end
|
|
|
// Pause here for program counter change of flow or memory write access
|
// Pause here for program counter change of flow or memory write access
|
// Load next instruction and increment PC
|
// Load next instruction and increment PC
|
// Default next_cpu_state is CONT
|
// Default next_cpu_state is CONT
|
Line 649... |
Line 654... |
begin
|
begin
|
end
|
end
|
|
|
// Pause here for memory read word access
|
// Pause here for memory read word access
|
// Load next instruction and increment PC
|
// Load next instruction and increment PC
|
{W_STALL, 16'b????????????????} :
|
{W_LOAD, 16'b????????????????} :
|
begin
|
begin
|
|
// alu_result = read_mem_data;
|
alu_result = load_data;
|
alu_result = load_data;
|
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
|
|
|
// Pause here for memory read byte access
|
// Pause here for memory read byte access
|
// Load next instruction and increment PC
|
// Load next instruction and increment PC
|
{B_STALL, 16'b????????????????} :
|
{B_LOAD, 16'b????????????????} :
|
begin
|
begin
|
|
// alu_result = {8'h00, read_mem_data[15:8]};
|
alu_result = {8'h00, load_data[15:8]};
|
alu_result = {8'h00, load_data[15:8]};
|
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
|
|
|
Line 674... |
Line 681... |
// 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
|
// Cycles - PAff
|
// Cycles - PAff
|
{CONT, 16'b0000000000000000} :
|
{CONT, 16'b0000000000000000} :
|
begin
|
begin
|
next_cpu_state = BREAK;
|
next_cpu_state = BREAK;
|
next_pc = program_counter - 16'h0002;
|
pc_incr_mux = 16'hfffe; // equals -2
|
|
next_pc = pc_sum;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
brk_set_dbg = 1'b1;
|
brk_set_dbg = 1'b1;
|
end
|
end
|
|
|
// Instruction = NOP, Op Code = 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
|
// Instruction = NOP, Op Code = 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
|
Line 689... |
Line 697... |
// Instruction = RTS, Op Code = 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
|
// Instruction = RTS, Op Code = 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
|
// Cycles - PA
|
// Cycles - PA
|
{CONT, 16'b0000001000000000} :
|
{CONT, 16'b0000001000000000} :
|
begin
|
begin
|
next_cpu_state = IDLE;
|
next_cpu_state = IDLE;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
end
|
end
|
|
|
// Instruction = SIF, Op Code = 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
|
// Instruction = SIF, Op Code = 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
|
// Sets the Interrupt Flag of the current channel (XGCHID) will be set.
|
// Sets the Interrupt Flag of the current channel (XGCHID) will be set.
|
Line 1264... |
Line 1273... |
begin
|
begin
|
if (!carry_flag)
|
if (!carry_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum; // There is a race condition when the default declaration is used
|
end
|
end
|
end
|
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
|
Line 1278... |
Line 1288... |
begin
|
begin
|
if (carry_flag)
|
if (carry_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1292... |
Line 1303... |
begin
|
begin
|
if (!zero_flag)
|
if (!zero_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1306... |
Line 1318... |
begin
|
begin
|
if (zero_flag)
|
if (zero_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1320... |
Line 1333... |
begin
|
begin
|
if (!negative_flag)
|
if (!negative_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1334... |
Line 1348... |
begin
|
begin
|
if (negative_flag)
|
if (negative_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1348... |
Line 1363... |
begin
|
begin
|
if (!overflow_flag)
|
if (!overflow_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1362... |
Line 1378... |
begin
|
begin
|
if (overflow_flag)
|
if (overflow_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1376... |
Line 1393... |
begin
|
begin
|
if (!(carry_flag || zero_flag))
|
if (!(carry_flag || zero_flag))
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1390... |
Line 1408... |
begin
|
begin
|
if (carry_flag || zero_flag)
|
if (carry_flag || zero_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1404... |
Line 1423... |
begin
|
begin
|
if (!(negative_flag ^ overflow_flag))
|
if (!(negative_flag ^ overflow_flag))
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1418... |
Line 1438... |
begin
|
begin
|
if (negative_flag ^ overflow_flag)
|
if (negative_flag ^ overflow_flag)
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1432... |
Line 1453... |
begin
|
begin
|
if (!(zero_flag || (negative_flag ^ overflow_flag)))
|
if (!(zero_flag || (negative_flag ^ overflow_flag)))
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1446... |
Line 1468... |
begin
|
begin
|
if (zero_flag || (negative_flag ^ overflow_flag))
|
if (zero_flag || (negative_flag ^ overflow_flag))
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = jump_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
end
|
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
|
Line 1458... |
Line 1481... |
// Cycles - PP
|
// Cycles - PP
|
{CONT, 16'b001111??????????} :
|
{CONT, 16'b001111??????????} :
|
begin
|
begin
|
next_cpu_state = S_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};
|
pc_incr_mux = bra_offset;
|
|
next_pc = pc_sum;
|
end
|
end
|
|
|
|
|
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
// Instruction Group -- Load and Store Instructions
|
// Instruction Group -- Load and Store Instructions
|
Line 1473... |
Line 1497... |
// 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 = B_STALL;
|
next_cpu_state = B_LOAD;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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
|
|
|
// 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
|
Line 1487... |
Line 1512... |
// 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 = W_STALL;
|
next_cpu_state = W_LOAD;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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
|
|
|
Line 1504... |
Line 1530... |
// Cycles - Pw
|
// Cycles - Pw
|
{CONT, 16'b01010???????????} :
|
{CONT, 16'b01010???????????} :
|
begin
|
begin
|
next_cpu_state = S_STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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
|
|
|
Line 1519... |
Line 1546... |
// Cycles - PW
|
// Cycles - PW
|
{CONT, 16'b01011???????????} :
|
{CONT, 16'b01011???????????} :
|
begin
|
begin
|
next_cpu_state = S_STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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
|
Line 1533... |
Line 1561... |
// 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 = B_STALL;
|
next_cpu_state = B_LOAD;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
data_access = 1'b1;
|
data_access = 1'b1;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
end
|
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
|
Line 1547... |
Line 1576... |
// 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 = W_STALL;
|
next_cpu_state = W_LOAD;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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
|
|
|
Line 1564... |
Line 1594... |
// Cycles - Pw
|
// Cycles - Pw
|
{CONT, 16'b01110?????????00} :
|
{CONT, 16'b01110?????????00} :
|
begin
|
begin
|
next_cpu_state = S_STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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
|
|
|
Line 1579... |
Line 1610... |
// Cycles - PW
|
// Cycles - PW
|
{CONT, 16'b01111?????????00} :
|
{CONT, 16'b01111?????????00} :
|
begin
|
begin
|
next_cpu_state = S_STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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
|
Line 1595... |
Line 1627... |
// 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 = B_STALL;
|
next_cpu_state = B_LOAD;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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;
|
Line 1615... |
Line 1648... |
// 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 = W_STALL;
|
next_cpu_state = W_LOAD;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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;
|
alu_result = rs2_data + 16'h0002;
|
alu_result = rs2_data + 16'h0002;
|
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
Line 1636... |
Line 1670... |
// Cycles - Pw
|
// Cycles - Pw
|
{CONT, 16'b01110?????????01} :
|
{CONT, 16'b01110?????????01} :
|
begin
|
begin
|
next_cpu_state = S_STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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;
|
alu_result = rs2_data + 16'h0001;
|
alu_result = rs2_data + 16'h0001;
|
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
Line 1655... |
Line 1690... |
// Cycles - PW
|
// Cycles - PW
|
{CONT, 16'b01111?????????01} :
|
{CONT, 16'b01111?????????01} :
|
begin
|
begin
|
next_cpu_state = S_STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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;
|
data_address = rs1_data + rs2_data;
|
data_address = rs1_data + rs2_data;
|
alu_result = rs2_data + 16'h0002;
|
alu_result = rs2_data + 16'h0002;
|
Line 1673... |
Line 1709... |
// 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 = B_STALL;
|
next_cpu_state = B_LOAD;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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;
|
Line 1691... |
Line 1728... |
// 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 = W_STALL;
|
next_cpu_state = W_LOAD;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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;
|
data_word_op = 1'b1;
|
data_word_op = 1'b1;
|
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
Line 1714... |
Line 1752... |
// Cycles - Pw
|
// Cycles - Pw
|
{CONT, 16'b01110?????????10} :
|
{CONT, 16'b01110?????????10} :
|
begin
|
begin
|
next_cpu_state = S_STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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;
|
data_address = rs1_data + alu_result;
|
data_address = rs1_data + alu_result;
|
sel_rd_field = 1'b0;
|
sel_rd_field = 1'b0;
|
Line 1735... |
Line 1774... |
// Cycles - PW
|
// Cycles - PW
|
{CONT, 16'b01111?????????10} :
|
{CONT, 16'b01111?????????10} :
|
begin
|
begin
|
next_cpu_state = S_STALL;
|
next_cpu_state = S_STALL;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
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;
|
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 2049... |
Line 2089... |
begin
|
begin
|
// synopsys translate_off
|
// synopsys translate_off
|
$display("\nOP Code Error\n");
|
$display("\nOP Code Error\n");
|
// synopsys translate_on
|
// synopsys translate_on
|
next_cpu_state = DEBUG;
|
next_cpu_state = DEBUG;
|
next_pc = program_counter;
|
pc_incr_mux = 16'h0000;
|
|
next_pc = pc_sum;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
op_code_error = 1'b1;
|
op_code_error = 1'b1;
|
end
|
end
|
endcase
|
endcase
|
|
|
end // always
|
end // always
|
|
|
xgate_barrel_shift barrel_shift(
|
xgate_barrel_shift barrel_shift(
|
// outputs
|
// outputs
|
.shift_out( shift_out ),
|
.shift_out( shift_out ),
|