Line 67... |
Line 67... |
input risc_clk,
|
input risc_clk,
|
input async_rst_b,
|
input async_rst_b,
|
input mem_req_ack, // Memory Bus available - data good
|
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_set, // Enter XGATE Debug Mode
|
|
input xgdbg_clear, // Leave 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 xgie, // XGATE Interrupt Enable
|
input brk_irq_ena, // Enable BRK instruction to generate interrupt
|
input brk_irq_ena, // Enable BRK instruction to generate interrupt
|
Line 186... |
Line 187... |
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 xgdbg_dly; //
|
reg cmd_change_pc; // Debug write to PC register
|
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.
|
// Generate an address for an op code fetch from an odd address or a word Load/Store from/to an odd address.
|
Line 202... |
Line 202... |
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 cpu_is_idle = (cpu_state == IDLE);
|
assign perif_wrt_ena = (cpu_is_idle && ~xge) || xgdbg;
|
assign perif_wrt_ena = (cpu_is_idle && ~xge) || debug_active;
|
|
|
// 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])
|
Line 224... |
Line 224... |
assign wrt_reg_sel = sel_rd_field ? op_code[10:8] : op_code[4:2];
|
assign wrt_reg_sel = sel_rd_field ? op_code[10:8] : op_code[4:2];
|
|
|
// Decode register write select for eather RD or RI/RS2
|
// Decode register write select for eather RD or RI/RS2
|
always @*
|
always @*
|
begin
|
begin
|
wrt_sel_xgr1 = (cpu_state == BOOT_2);
|
wrt_sel_xgr1 = (cpu_state == BOOT_3);
|
wrt_sel_xgr2 = 1'b0;
|
wrt_sel_xgr2 = 1'b0;
|
wrt_sel_xgr3 = 1'b0;
|
wrt_sel_xgr3 = 1'b0;
|
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;
|
Line 292... |
Line 292... |
software_error <= addr_error || op_code_error ||
|
software_error <= addr_error || op_code_error ||
|
(brk_set_dbg && brk_irq_ena) || (software_error && !xgsweif_c);
|
(brk_set_dbg && brk_irq_ena) || (software_error && !xgsweif_c);
|
|
|
assign xg_sw_irq = software_error && xgie;
|
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
|
// Latch the debug state, set by eather xgdb or BRK instructions
|
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 )
|
debug_active <= 1'b0;
|
debug_active <= 1'b0;
|
else
|
else
|
debug_active <= !xgdbg_negedge && (xgdbg || brk_set_dbg || op_code_error || debug_active);
|
debug_active <= !xgdbg_clear && (xgdbg_set || brk_set_dbg || op_code_error || debug_active);
|
|
|
// Convert xgss (Single Step Pulse) to a one risc_clk wide pulse
|
// Convert xgss (Single Step Pulse) to a one risc_clk wide pulse
|
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 )
|
xgss_edge <= 1'b0;
|
xgss_edge <= 1'b0;
|
Line 353... |
Line 344... |
if ( !async_rst_b )
|
if ( !async_rst_b )
|
program_counter <= 16'h0000;
|
program_counter <= 16'h0000;
|
else
|
else
|
program_counter <= (write_xgpc && perif_wrt_ena) ? perif_data : (mem_req_ack ? next_pc : program_counter);
|
program_counter <= (write_xgpc && perif_wrt_ena) ? perif_data : (mem_req_ack ? next_pc : program_counter);
|
|
|
|
// Debug Change Program Counter Register
|
|
always @(posedge risc_clk or negedge async_rst_b)
|
|
if ( !async_rst_b )
|
|
cmd_change_pc <= 1'b0;
|
|
else
|
|
cmd_change_pc <= write_xgpc && perif_wrt_ena;
|
|
|
// 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
|
carry_flag <= 1'b0;
|
carry_flag <= 1'b0;
|
Line 557... |
Line 555... |
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 : DEBUG) : IDLE;
|
next_cpu_state = xge ? ((single_step || !debug_active) ? CONT : (cmd_change_pc ? LD_INST : DEBUG)) : IDLE;
|
load_next_inst = 1'b0;
|
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
|
// Load next instruction and increment PC
|
// Load next instruction and increment PC
|