Line 55... |
Line 55... |
output reg negative_flag,
|
output reg negative_flag,
|
output reg carry_flag,
|
output reg carry_flag,
|
output reg overflow_flag,
|
output reg overflow_flag,
|
output reg [ 6:0] xgchid,
|
output reg [ 6:0] xgchid,
|
output reg [MAX_CHANNEL:0] xgif, // XGATE Interrupt Flag
|
output reg [MAX_CHANNEL:0] xgif, // XGATE Interrupt Flag
|
|
output xg_sw_irq, // Xgate Software interrupt
|
output [ 7:0] host_semap, // Semaphore status for host
|
output [ 7:0] host_semap, // Semaphore status for host
|
|
output reg debug_active, // Latch to control debug mode in the RISC state machine
|
|
|
|
|
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,
|
Line 69... |
Line 71... |
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
|
input [ 6:0] int_req, // Encoded interrupt request
|
input [ 6:0] int_req, // Encoded interrupt request
|
|
input xgie, // XGATE Interrupt Enable
|
|
input brk_irq_ena, // Enable BRK instruction to generate interrupt
|
input write_xgsem, // Write Strobe for XGSEM register
|
input write_xgsem, // Write Strobe for XGSEM register
|
input write_xgccr, // Write Strobe for XGATE Condition Code Register
|
input write_xgccr, // Write Strobe for XGATE Condition Code Register
|
input write_xgpc, // Write Strobe for XGATE Program Counter
|
input write_xgpc, // Write Strobe for XGATE Program Counter
|
input write_xgr7, // Write Strobe for XGATE Data Register R7
|
input write_xgr7, // Write Strobe for XGATE Data Register R7
|
input write_xgr6, // Write Strobe for XGATE Data Register R6
|
input write_xgr6, // Write Strobe for XGATE Data Register R6
|
input write_xgr5, // Write Strobe for XGATE Data Register R5
|
input write_xgr5, // Write Strobe for XGATE Data Register R5
|
input write_xgr4, // Write Strobe for XGATE Data Register R4
|
input write_xgr4, // Write Strobe for XGATE Data Register R4
|
input write_xgr3, // Write Strobe for XGATE Data Register R3
|
input write_xgr3, // Write Strobe for XGATE Data Register R3
|
input write_xgr2, // Write Strobe for XGATE Data Register R2
|
input write_xgr2, // Write Strobe for XGATE Data Register R2
|
input write_xgr1, // Write Strobe for XGATE Data Register R1
|
input write_xgr1, // Write Strobe for XGATE Data Register R1
|
|
input xgsweif_c, // Clear Software Flag
|
input clear_xgif_7, // Strobe for decode to clear interrupt flag bank 7
|
input clear_xgif_7, // Strobe for decode to clear interrupt flag bank 7
|
input clear_xgif_6, // Strobe for decode to clear interrupt flag bank 6
|
input clear_xgif_6, // Strobe for decode to clear interrupt flag bank 6
|
input clear_xgif_5, // Strobe for decode to clear interrupt flag bank 5
|
input clear_xgif_5, // Strobe for decode to clear interrupt flag bank 5
|
input clear_xgif_4, // Strobe for decode to clear interrupt flag bank 4
|
input clear_xgif_4, // Strobe for decode to clear interrupt flag bank 4
|
input clear_xgif_3, // Strobe for decode to clear interrupt flag bank 3
|
input clear_xgif_3, // Strobe for decode to clear interrupt flag bank 3
|
Line 98... |
Line 103... |
|
|
// 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
|
DEBUG = 4'b0011, //
|
S_STALL = 4'b0010, // Simple Stall while updating PC after change of flow
|
BOOT_1 = 4'b0100, //
|
W_STALL = 4'b0011, // Stall while doing memory word read access
|
BOOT_2 = 4'b0101, //
|
B_STALL = 4'b0100, // Stall while doing memory byte read access
|
BOOT_3 = 4'b0110, //
|
BREAK = 4'b0101, // Stop in this state after BRK instruction
|
S_STALL = 4'b0111, // Simple Stall while updating PC after change of flow
|
BREAK_2 = 4'b0110, // Advance PC after Single Step command
|
W_STALL = 4'b1000, // Stall while doing memory word read access
|
LD_INST = 4'b0111, // Load Instruction in Debug mode
|
B_STALL = 4'b1001; // Stall while doing memory byte read access
|
DEBUG = 4'b1000, // Stop in this state while waiting for debug commands
|
|
BOOT_1 = 4'b1001, //
|
|
BOOT_2 = 4'b1010, //
|
|
BOOT_3 = 4'b1011; //
|
|
|
|
|
// 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 [ 3:0] cpu_state;
|
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;
|
reg [15:0] program_counter; // Program Counter register
|
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; // 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,
|
|
|
reg data_access; // Pseudo Register, RAM access in proccess
|
reg data_access; // Pseudo Register, RAM access in proccess
|
reg data_write; // Pseudo Register, RAM access is write operation
|
reg data_write; // Pseudo Register, RAM access is write operation
|
reg data_word_op; // Pseudo Register, RAM access operation is 16 bits(word)
|
reg data_word_op; // Pseudo Register, RAM access operation is 16 bits(word)
|
reg [15:0] data_address; // Pseudo Register, Address for RAM data read or write
|
reg [15:0] data_address; // Pseudo Register, Address for RAM data read or write
|
reg [15:0] load_data;
|
reg [15:0] load_data; // Data captured from WISHBONE Master bus for Load instructions
|
|
|
reg [ 6:0] set_irq_flag;
|
reg [ 6:0] set_irq_flag; // Pseudo Register, pulse for setting irq output register
|
|
|
reg next_zero; // Pseudo Register,
|
reg next_zero; // Pseudo Register,
|
reg next_negative; // Pseudo Register,
|
reg next_negative; // Pseudo Register,
|
reg next_carry; // Pseudo Register,
|
reg next_carry; // Pseudo Register,
|
reg next_overflow; // Pseudo Register,
|
reg next_overflow; // Pseudo Register,
|
|
|
|
reg op_code_error; // Pseudo Register,
|
|
reg software_error; // OP Code error, Address Error, BRK Error
|
|
wire addr_error; // Decode Addressing error
|
|
|
reg set_semaph; // Pseudo Register,
|
reg set_semaph; // Pseudo Register,
|
reg clear_semaph; // Pseudo Register,
|
reg clear_semaph; // Pseudo Register,
|
reg [ 2:0] semaph_risc; // Pseudo Register,
|
reg [ 2:0] semaph_risc; // Pseudo Register,
|
reg [ 7:0] semap_risc_bit; // Pseudo Register,
|
reg [ 7:0] semap_risc_bit; // Pseudo Register,
|
wire [ 7:0] risc_semap; // Semaphore status bit for RISC
|
wire [ 7:0] risc_semap; // Semaphore status bit for RISC
|
Line 168... |
Line 180... |
reg [ 4:0] shift_ammount;
|
reg [ 4:0] shift_ammount;
|
reg [15:0] shift_filler;
|
reg [15:0] shift_filler;
|
|
|
wire start_thread;
|
wire start_thread;
|
|
|
|
wire cpu_is_idle; // Processor is in the IDLE state
|
|
wire perif_wrt_ena; // Enable for Salve writes to CPU registers
|
|
|
|
reg xgss_edge; // Flop for edge detection
|
|
wire single_step; // Pulse to trigger a single instruction execution in debug mode
|
|
reg brk_set_dbg; // Pulse to set debug_active from instruction decoder
|
|
reg xgdbg_dly; //
|
|
wire xgdbg_negedge; //
|
|
|
|
|
assign xgate_address = data_access ? data_address : program_counter;
|
assign xgate_address = data_access ? data_address : program_counter;
|
|
|
|
// Generate an address for an op code fetch from an odd address or a word Load/Store from/to an odd address.
|
|
assign addr_error = xgate_address[0] && (load_next_inst || (data_access && data_word_op));
|
|
|
assign write_mem_strb_l = data_access && data_write && (data_word_op || !data_address[0]);
|
assign write_mem_strb_l = data_access && data_write && (data_word_op || !data_address[0]);
|
assign write_mem_strb_h = data_access && data_write && (data_word_op || data_address[0]);
|
assign write_mem_strb_h = data_access && data_write && (data_word_op || data_address[0]);
|
assign write_mem_data = (write_mem_strb_l || write_mem_strb_h) ? rd_data : 16'b0;
|
assign write_mem_data = (write_mem_strb_l || write_mem_strb_h) ? rd_data : 16'b0;
|
|
|
assign start_thread = xge && (|int_req);
|
assign start_thread = xge && (|int_req);
|
|
|
|
assign cpu_is_idle = (cpu_state == IDLE);
|
|
assign perif_wrt_ena = (cpu_is_idle && ~xge) || xgdbg;
|
|
|
// Decode register select for RD and RS
|
// Decode register select for RD and RS
|
always @*
|
always @*
|
begin
|
begin
|
case (op_code[10:8])
|
case (op_code[10:8])
|
3'b001 : rd_data = xgr1;
|
3'b001 : rd_data = xgr1;
|
Line 256... |
Line 282... |
bf_mux_mask[k] = 1'b1;
|
bf_mux_mask[k] = 1'b1;
|
k = k + 1;
|
k = k + 1;
|
end
|
end
|
end
|
end
|
|
|
|
// Software Error Interrupt Latch
|
|
always @(posedge risc_clk or negedge async_rst_b)
|
|
if ( !async_rst_b )
|
|
software_error <= 1'b0;
|
|
else
|
|
software_error <= addr_error || op_code_error ||
|
|
(brk_set_dbg && brk_irq_ena) || (software_error && !xgsweif_c);
|
|
|
|
assign xg_sw_irq = software_error && xgie;
|
|
|
|
// Edge detect xgdbg
|
|
always @(posedge risc_clk or negedge async_rst_b)
|
|
if ( !async_rst_b )
|
|
xgdbg_dly <= 1'b0;
|
|
else
|
|
xgdbg_dly <= xgdbg;
|
|
|
|
assign xgdbg_negedge = !xgdbg && xgdbg_dly;
|
|
|
|
// Latch the debug state, set by eather xgdb or BRK instructions
|
|
always @(posedge risc_clk or negedge async_rst_b)
|
|
if ( !async_rst_b )
|
|
debug_active <= 1'b0;
|
|
else
|
|
debug_active <= !xgdbg_negedge && (xgdbg || brk_set_dbg || op_code_error || debug_active);
|
|
|
|
// Convert xgss (Single Step Pulse) to a one risc_clk wide pulse
|
|
always @(posedge risc_clk or negedge async_rst_b)
|
|
if ( !async_rst_b )
|
|
xgss_edge <= 1'b0;
|
|
else
|
|
xgss_edge <= xgss;
|
|
|
|
assign single_step = xgss && !xgss_edge;
|
|
|
|
|
// 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
|
Line 275... |
Line 337... |
// 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) && mem_req_ack) ? int_req : xgchid;
|
xgchid <= (cpu_is_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;
|
Line 289... |
Line 351... |
// 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 <= mem_req_ack ? next_pc : program_counter;
|
program_counter <= (write_xgpc && perif_wrt_ena) ? perif_data : (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 302... |
Line 364... |
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] : (mem_req_ack ? next_carry : carry_flag);
|
carry_flag <= (write_xgccr && perif_wrt_ena) ? perif_data[0] : (mem_req_ack ? next_carry : carry_flag);
|
overflow_flag <= write_xgccr ? perif_data[1] : (mem_req_ack ? next_overflow : overflow_flag);
|
overflow_flag <= (write_xgccr && perif_wrt_ena) ? perif_data[1] : (mem_req_ack ? next_overflow : overflow_flag);
|
zero_flag <= write_xgccr ? perif_data[2] : (mem_req_ack ? next_zero : zero_flag);
|
zero_flag <= (write_xgccr && perif_wrt_ena) ? perif_data[2] : (mem_req_ack ? next_zero : zero_flag);
|
negative_flag <= write_xgccr ? perif_data[3] : (mem_req_ack ? next_negative : negative_flag);
|
negative_flag <= (write_xgccr && perif_wrt_ena) ? perif_data[3] : (mem_req_ack ? next_negative : negative_flag);
|
end
|
end
|
|
|
// Interrupt Flag next value
|
// Interrupt Flag next value
|
always @*
|
always @*
|
begin
|
begin
|
j = 0;
|
j = 0;
|
i = 0;
|
|
while (j <= MAX_CHANNEL)
|
while (j <= MAX_CHANNEL)
|
begin
|
begin
|
if (j < 16)
|
xgif_d[j] = xgif[j] || (set_irq_flag == j);
|
xgif_d[j] = (~(clear_xgif_0 && clear_xgif_data[i]) && xgif[j]) || (set_irq_flag == j);
|
|
if (15 < j < 32)
|
|
xgif_d[j] = (~(clear_xgif_1 && clear_xgif_data[i]) && xgif[j]) || (set_irq_flag == j);
|
|
if (31 < j < 48)
|
|
xgif_d[j] = (~(clear_xgif_2 && clear_xgif_data[i]) && xgif[j]) || (set_irq_flag == j);
|
|
if (47 < j < 64)
|
|
xgif_d[j] = (~(clear_xgif_3 && clear_xgif_data[i]) && xgif[j]) || (set_irq_flag == j);
|
|
if (63 < j < 80)
|
|
xgif_d[j] = (~(clear_xgif_4 && clear_xgif_data[i]) && xgif[j]) || (set_irq_flag == j);
|
|
if (79 < j < 96)
|
|
xgif_d[j] = (~(clear_xgif_5 && clear_xgif_data[i]) && xgif[j]) || (set_irq_flag == j);
|
|
if (95 < j < 112)
|
|
xgif_d[j] = (~(clear_xgif_6 && clear_xgif_data[i]) && xgif[j]) || (set_irq_flag == j);
|
|
if (111 < j < 128)
|
|
xgif_d[j] = (~(clear_xgif_7 && clear_xgif_data[i]) && xgif[j]) || (set_irq_flag == j);
|
|
if (i < 15)
|
|
i = i + 1;
|
|
else
|
|
i = 0;
|
|
j = j + 1;
|
j = j + 1;
|
end
|
end
|
|
if (clear_xgif_0)
|
|
xgif_d[15: 0] = ~clear_xgif_data & xgif[15: 0];
|
|
if (clear_xgif_1)
|
|
xgif_d[31:16] = ~clear_xgif_data & xgif[31:16];
|
|
if (clear_xgif_2)
|
|
xgif_d[47:32] = ~clear_xgif_data & xgif[47:32];
|
|
if (clear_xgif_3)
|
|
xgif_d[63:48] = ~clear_xgif_data & xgif[63:48];
|
|
if (clear_xgif_4)
|
|
xgif_d[79:64] = ~clear_xgif_data & xgif[79:64];
|
|
if (clear_xgif_5)
|
|
xgif_d[95:80] = ~clear_xgif_data & xgif[95:80];
|
|
if (clear_xgif_6)
|
|
xgif_d[111:96] = ~clear_xgif_data & xgif[111:96];
|
|
if (clear_xgif_7)
|
|
xgif_d[127:112] = ~clear_xgif_data & xgif[127:112];
|
end
|
end
|
|
|
// Interrupt Flag Registers
|
// Interrupt Flag Registers
|
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 )
|
Line 361... |
Line 419... |
xgr6 <= 16'b0;
|
xgr6 <= 16'b0;
|
xgr7 <= 16'b0;
|
xgr7 <= 16'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
xgr1 <= write_xgr1 ? perif_data :
|
xgr1 <= (write_xgr1 && perif_wrt_ena) ? perif_data :
|
{((wrt_sel_xgr1 && ena_rd_high_byte) ? alu_result[15:8] : xgr1[15:8]),
|
{((wrt_sel_xgr1 && ena_rd_high_byte) ? alu_result[15:8] : xgr1[15:8]),
|
((wrt_sel_xgr1 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr1[ 7:0])};
|
((wrt_sel_xgr1 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr1[ 7:0])};
|
xgr2 <= write_xgr2 ? perif_data :
|
xgr2 <= (write_xgr2 && perif_wrt_ena) ? perif_data :
|
{((wrt_sel_xgr2 && ena_rd_high_byte) ? alu_result[15:8] : xgr2[15:8]),
|
{((wrt_sel_xgr2 && ena_rd_high_byte) ? alu_result[15:8] : xgr2[15:8]),
|
((wrt_sel_xgr2 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr2[ 7:0])};
|
((wrt_sel_xgr2 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr2[ 7:0])};
|
xgr3 <= write_xgr3 ? perif_data :
|
xgr3 <= (write_xgr3 && perif_wrt_ena) ? perif_data :
|
{((wrt_sel_xgr3 && ena_rd_high_byte) ? alu_result[15:8] : xgr3[15:8]),
|
{((wrt_sel_xgr3 && ena_rd_high_byte) ? alu_result[15:8] : xgr3[15:8]),
|
((wrt_sel_xgr3 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr3[ 7:0])};
|
((wrt_sel_xgr3 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr3[ 7:0])};
|
xgr4 <= write_xgr4 ? perif_data :
|
xgr4 <= (write_xgr4 && perif_wrt_ena) ? perif_data :
|
{((wrt_sel_xgr4 && ena_rd_high_byte) ? alu_result[15:8] : xgr4[15:8]),
|
{((wrt_sel_xgr4 && ena_rd_high_byte) ? alu_result[15:8] : xgr4[15:8]),
|
((wrt_sel_xgr4 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr4[ 7:0])};
|
((wrt_sel_xgr4 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr4[ 7:0])};
|
xgr5 <= write_xgr5 ? perif_data :
|
xgr5 <= (write_xgr5 && perif_wrt_ena) ? perif_data :
|
{((wrt_sel_xgr5 && ena_rd_high_byte) ? alu_result[15:8] : xgr5[15:8]),
|
{((wrt_sel_xgr5 && ena_rd_high_byte) ? alu_result[15:8] : xgr5[15:8]),
|
((wrt_sel_xgr5 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr5[ 7:0])};
|
((wrt_sel_xgr5 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr5[ 7:0])};
|
xgr6 <= write_xgr6 ? perif_data :
|
xgr6 <= (write_xgr6 && perif_wrt_ena) ? perif_data :
|
{((wrt_sel_xgr6 && ena_rd_high_byte) ? alu_result[15:8] : xgr6[15:8]),
|
{((wrt_sel_xgr6 && ena_rd_high_byte) ? alu_result[15:8] : xgr6[15:8]),
|
((wrt_sel_xgr6 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr6[ 7:0])};
|
((wrt_sel_xgr6 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr6[ 7:0])};
|
xgr7 <= write_xgr7 ? perif_data :
|
xgr7 <= (write_xgr7 && perif_wrt_ena) ? perif_data :
|
{((wrt_sel_xgr7 && ena_rd_high_byte) ? alu_result[15:8] : xgr7[15:8]),
|
{((wrt_sel_xgr7 && ena_rd_high_byte) ? alu_result[15:8] : xgr7[15:8]),
|
((wrt_sel_xgr7 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr7[ 7:0])};
|
((wrt_sel_xgr7 && ena_rd_low_byte) ? alu_result[ 7:0] : xgr7[ 7:0])};
|
end
|
end
|
|
|
// V Ñ Vector fetch: always an aligned word read, lasts for at least one RISC core cycle
|
// V Ñ Vector fetch: always an aligned word read, lasts for at least one RISC core cycle
|
Line 400... |
Line 458... |
always @*
|
always @*
|
begin
|
begin
|
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 = 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;
|
next_pc = program_counter + 16'h0002;
|
next_pc = program_counter + 16'h0002;
|
|
|
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;
|
|
|
|
brk_set_dbg = 1'b0;
|
|
op_code_error = 1'b0;
|
|
|
alu_result = 16'h0000;
|
alu_result = 16'h0000;
|
sel_rd_field = 1'b1;
|
sel_rd_field = 1'b1;
|
|
|
data_access = 1'b0;
|
data_access = 1'b0;
|
data_word_op = 1'b0;
|
data_word_op = 1'b0;
|
Line 472... |
Line 534... |
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
|
|
|
|
{BREAK, 16'b????????????????} :
|
|
begin
|
|
next_cpu_state = xge ? ((single_step || !debug_active) ? BREAK_2 : BREAK) : IDLE;
|
|
load_next_inst = 1'b0;
|
|
next_pc = program_counter;
|
|
end
|
|
|
|
{BREAK_2, 16'b????????????????} :
|
|
begin
|
|
next_cpu_state = LD_INST;
|
|
load_next_inst = 1'b0;
|
|
next_pc = program_counter + 2;
|
|
end
|
|
|
|
{LD_INST, 16'b????????????????} :
|
|
begin
|
|
next_cpu_state = DEBUG;
|
|
load_next_inst = 1'b1;
|
|
next_pc = program_counter;
|
|
end
|
|
|
{DEBUG, 16'b????????????????} :
|
{DEBUG, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = xge ? DEBUG : IDLE;
|
next_cpu_state = xge ? ((single_step || !debug_active) ? CONT : 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
|
// 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
|
{S_STALL, 16'b????????????????} :
|
{S_STALL, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = CONT;
|
|
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_STALL, 16'b????????????????} :
|
Line 512... |
Line 595... |
|
|
// 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 = DEBUG;
|
next_cpu_state = BREAK;
|
next_pc = program_counter;
|
next_pc = program_counter - 16'h0002;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
|
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
|
{CONT, 16'b0000000100000000} :
|
{CONT, 16'b0000000100000000} :
|
begin
|
begin
|
Line 1884... |
Line 1968... |
alu_result = {op_code[7:0], 8'b0};
|
alu_result = {op_code[7:0], 8'b0};
|
end
|
end
|
default :
|
default :
|
begin
|
begin
|
$display("\nOP Code Error\n");
|
$display("\nOP Code Error\n");
|
|
next_cpu_state = DEBUG;
|
|
next_pc = program_counter;
|
|
load_next_inst = 1'b0;
|
|
op_code_error = 1'b1;
|
end
|
end
|
endcase
|
endcase
|
end // always
|
end // always
|
|
|
xgate_barrel_shift barrel_shift(
|
xgate_barrel_shift barrel_shift(
|