Line 74... |
Line 74... |
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 xgie, // XGATE Interrupt Enable
|
input brk_irq_ena, // Enable BRK instruction to generate interrupt
|
input brk_irq_ena, // Enable BRK instruction to generate interrupt
|
|
input write_xgchid, // Write Strobe for XGCHID register
|
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
|
Line 113... |
Line 114... |
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, //
|
BOOT_2 = 4'b1010, //
|
BOOT_2 = 4'b1010, //
|
BOOT_3 = 4'b1011; //
|
BOOT_3 = 4'b1011, //
|
|
CHG_CHID = 4'b1100;
|
|
|
|
|
// 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,
|
Line 179... |
Line 181... |
wire shift_rollover;
|
wire shift_rollover;
|
reg shift_left;
|
reg shift_left;
|
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; // Signle to pop RISC core out of IDLE State
|
|
|
wire cpu_is_idle; // Processor is in the IDLE state
|
wire cpu_is_idle; // Processor is in the IDLE state
|
wire perif_wrt_ena; // Enable for Salve writes to CPU registers
|
wire perif_wrt_ena; // Enable for Salve writes to CPU registers
|
|
|
reg xgss_edge; // Flop for edge detection
|
reg xgss_edge; // Flop for edge detection
|
wire single_step; // Pulse to trigger a single instruction execution in debug mode
|
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 brk_set_dbg; // Pulse to set debug_active from instruction decoder
|
reg cmd_change_pc; // Debug write to PC register
|
reg cmd_change_pc; // Debug write to PC register
|
|
|
|
reg [ 1:0] chid_sm_ns; // Pseudo Register,
|
|
reg [ 1:0] chid_sm; //
|
|
wire chid_goto_idle; //
|
|
|
|
// Debug states for change CHID
|
|
parameter [1:0] CHID_IDLE = 2'b00,
|
|
CHID_TEST = 2'b10,
|
|
CHID_WAIT = 2'b11;
|
|
|
|
|
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.
|
// 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 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) && !debug_active;
|
|
|
assign cpu_is_idle = (cpu_state == IDLE);
|
assign cpu_is_idle = (cpu_state == IDLE);
|
assign perif_wrt_ena = (cpu_is_idle && ~xge) || debug_active;
|
assign perif_wrt_ena = (cpu_is_idle && ~xge) || debug_active;
|
|
|
// Decode register select for RD and RS
|
// Decode register select for RD and RS
|
Line 328... |
Line 339... |
// 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_is_idle && mem_req_ack) ? int_req : xgchid;
|
xgchid <= (write_xgchid && debug_active) ? perif_data[6:0] : ((cpu_is_idle && mem_req_ack) ? int_req : xgchid);
|
|
|
|
// Channel Change Debug state machine register
|
|
always @(posedge risc_clk or negedge async_rst_b)
|
|
if ( !async_rst_b )
|
|
chid_sm <= CHID_IDLE;
|
|
else
|
|
chid_sm <= chid_sm_ns;
|
|
|
|
// Channel Change Debug next state
|
|
always @*
|
|
case (chid_sm)
|
|
CHID_IDLE:
|
|
if ( write_xgchid && debug_active )
|
|
chid_sm_ns = CHID_TEST;
|
|
CHID_TEST:
|
|
if ( !((cpu_state == IDLE) || (cpu_state == CHG_CHID)) && (|xgchid) )
|
|
chid_sm_ns = CHID_IDLE;
|
|
else
|
|
chid_sm_ns = CHID_WAIT;
|
|
CHID_WAIT:
|
|
if ( (cpu_state == IDLE) || (cpu_state == CHG_CHID) )
|
|
chid_sm_ns = CHID_IDLE;
|
|
else
|
|
chid_sm_ns = CHID_WAIT;
|
|
default : chid_sm_ns = CHID_IDLE;
|
|
endcase
|
|
|
|
assign chid_goto_idle = (chid_sm == CHID_WAIT);
|
|
|
// 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 497... |
Line 536... |
next_cpu_state = start_thread ? BOOT_1 : IDLE;
|
next_cpu_state = start_thread ? BOOT_1 : IDLE;
|
next_pc = program_counter;
|
next_pc = program_counter;
|
load_next_inst = 1'b0;
|
load_next_inst = 1'b0;
|
end
|
end
|
|
|
|
{CHG_CHID, 16'b????????????????} :
|
|
begin
|
|
if (!xge)
|
|
next_cpu_state = IDLE;
|
|
else if (single_step || !debug_active)
|
|
next_cpu_state = BOOT_1;
|
|
else
|
|
next_cpu_state = CHG_CHID;
|
|
|
|
next_pc = program_counter;
|
|
load_next_inst = 1'b0;
|
|
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;
|
next_pc = program_counter;
|
Line 534... |
Line 586... |
alu_result = load_data;
|
alu_result = load_data;
|
end
|
end
|
|
|
{BREAK, 16'b????????????????} :
|
{BREAK, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = xge ? ((single_step || !debug_active) ? BREAK_2 : BREAK) : IDLE;
|
if (!xge)
|
|
next_cpu_state = IDLE;
|
|
else if (single_step || !debug_active)
|
|
next_cpu_state = BREAK_2;
|
|
else if (chid_goto_idle)
|
|
next_cpu_state = CHG_CHID;
|
|
else
|
|
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;
|
next_pc = program_counter;
|
end
|
end
|
|
|
{BREAK_2, 16'b????????????????} :
|
{BREAK_2, 16'b????????????????} :
|
Line 555... |
Line 617... |
next_pc = program_counter;
|
next_pc = program_counter;
|
end
|
end
|
|
|
{DEBUG, 16'b????????????????} :
|
{DEBUG, 16'b????????????????} :
|
begin
|
begin
|
next_cpu_state = xge ? ((single_step || !debug_active) ? CONT : (cmd_change_pc ? LD_INST : DEBUG)) : IDLE;
|
if (!xge)
|
|
next_cpu_state = IDLE;
|
|
else if (single_step || !debug_active)
|
|
next_cpu_state = CONT;
|
|
else if (cmd_change_pc)
|
|
next_cpu_state = LD_INST;
|
|
else if (chid_goto_idle)
|
|
next_cpu_state = CHG_CHID;
|
|
else
|
|
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;
|
next_pc = program_counter;
|
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
|