Line 59... |
Line 59... |
output reg [ 6:0] xgchid,
|
output reg [ 6:0] xgchid,
|
output reg [127:0] xgif_status, // XGATE Interrupt Flag
|
output reg [127:0] xgif_status, // XGATE Interrupt Flag
|
output xg_sw_irq, // Xgate Software interrupt
|
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
|
output reg debug_active, // Latch to control debug mode in the RISC state machine
|
|
output debug_ack, // Clear debug register
|
|
output single_step, // Pulse to trigger a single instruction execution in debug mode
|
|
|
|
|
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 mem_req_ack, // Memory Bus available - data good
|
|
input ss_mem_ack, // WISHBONE Bus has granted single step memory access
|
input xge, // XGATE Module Enable
|
input xge, // XGATE Module Enable
|
input debug_mode_i, // Force RISC core into debug mode
|
input debug_mode_i, // Force RISC core into debug mode
|
input xgdbg_set, // Enter XGATE Debug Mode
|
input xgdbg_set, // Enter XGATE Debug Mode, pulse
|
input xgdbg_clear, // Leave 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
|
Line 186... |
Line 189... |
wire [15:0] shift_out;
|
wire [15:0] shift_out;
|
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;
|
|
reg [15:0] bf_mux_mask; // Mask for controlling mux's in Bit Field Insert Instructions
|
|
|
wire start_thread; // Signle to pop RISC core out of IDLE State
|
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
|
|
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 debug_edge; // Reg for edge detection
|
|
|
reg [ 1:0] chid_sm_ns; // Pseudo Register for State Machine next state logic,
|
reg [ 1:0] chid_sm_ns; // Pseudo Register for State Machine next state logic,
|
reg [ 1:0] chid_sm; //
|
reg [ 1:0] chid_sm; //
|
wire chid_goto_idle; //
|
wire chid_goto_idle; //
|
|
|
Line 212... |
Line 216... |
assign bra_offset = {{5{op_code[9]}}, op_code[9: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 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 || (start_thread);
|
|
assign mem_access = data_access || load_next_inst || (cpu_state == CONT) ||
|
|
(cpu_state == BREAK_2) || (start_thread);
|
|
|
// 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]);
|
Line 282... |
Line 288... |
3'b110 : rs2_data = xgr6;
|
3'b110 : rs2_data = xgr6;
|
3'b111 : rs2_data = xgr7;
|
3'b111 : rs2_data = xgr7;
|
default : rs2_data = 16'h0; // XGR0 is always Zero
|
default : rs2_data = 16'h0; // XGR0 is always Zero
|
endcase
|
endcase
|
|
|
reg [15:0] bf_mux_mask; // Mask for controlling mux's in Bit Field Insert Instructions
|
|
// Decode mux select mask for Bit Field Insert Instructions
|
// Decode mux select mask for Bit Field Insert Instructions
|
always @*
|
always @*
|
begin
|
begin
|
k = 0;
|
k = 0;
|
while (k < 16)
|
while (k < 16)
|
Line 309... |
Line 314... |
assign xg_sw_irq = software_error && xgie;
|
assign xg_sw_irq = software_error && xgie;
|
|
|
// 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 )
|
|
begin
|
debug_active <= 1'b0;
|
debug_active <= 1'b0;
|
|
debug_edge <= 0;
|
|
end
|
else
|
else
|
debug_active <= !xgdbg_clear && (xgdbg_set || brk_set_dbg || op_code_error || debug_active);
|
begin
|
|
debug_active <= !xgdbg_clear && ((xgdbg_set && mem_req_ack && (next_cpu_state == CONT)) || brk_set_dbg || op_code_error || debug_active);
|
|
debug_edge <= debug_active;
|
|
end
|
|
|
|
assign debug_ack = debug_active && !debug_edge; // Posedge of 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;
|
else
|
else
|
xgss_edge <= xgss;
|
xgss_edge <= xgss;
|
|
|
assign single_step = xgss && !xgss_edge;
|
assign single_step = (xgss && !xgss_edge) || (!debug_active && debug_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
|
cpu_state <= mem_req_ack ? next_cpu_state : cpu_state;
|
cpu_state <= (mem_req_ack || (chid_sm != CHID_IDLE)) ? 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;
|
Line 394... |
Line 407... |
// Debug Change Program Counter Register
|
// Debug Change 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 )
|
cmd_change_pc <= 1'b0;
|
cmd_change_pc <= 1'b0;
|
else
|
else
|
cmd_change_pc <= |write_xgpc && perif_wrt_ena;
|
cmd_change_pc <= (|write_xgpc && perif_wrt_ena) || (cmd_change_pc && !mem_req_ack);
|
|
|
// 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 562... |
Line 575... |
|
|
{CHG_CHID, 16'b????????????????} :
|
{CHG_CHID, 16'b????????????????} :
|
begin
|
begin
|
if (!xge)
|
if (!xge)
|
next_cpu_state = IDLE;
|
next_cpu_state = IDLE;
|
else if (single_step || !debug_active)
|
else if (ss_mem_ack || !debug_active)
|
next_cpu_state = BOOT_1;
|
next_cpu_state = BOOT_1;
|
else
|
else
|
next_cpu_state = CHG_CHID;
|
next_cpu_state = CHG_CHID;
|
|
|
pc_incr_mux = 16'h0000;
|
pc_incr_mux = 16'h0000;
|
Line 611... |
Line 624... |
|
|
{BREAK, 16'b????????????????} :
|
{BREAK, 16'b????????????????} :
|
begin
|
begin
|
if (!xge)
|
if (!xge)
|
next_cpu_state = IDLE;
|
next_cpu_state = IDLE;
|
else if (single_step || !debug_active)
|
else if (ss_mem_ack || !debug_active)
|
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;
|
Line 639... |
Line 652... |
|
|
{DEBUG, 16'b????????????????} :
|
{DEBUG, 16'b????????????????} :
|
begin
|
begin
|
if (!xge)
|
if (!xge)
|
next_cpu_state = IDLE;
|
next_cpu_state = IDLE;
|
else if (single_step || !debug_active)
|
else if (ss_mem_ack || !debug_active)
|
next_cpu_state = CONT;
|
next_cpu_state = CONT;
|
else if (cmd_change_pc)
|
else if (cmd_change_pc)
|
next_cpu_state = LD_INST;
|
next_cpu_state = LD_INST;
|
else if (chid_goto_idle)
|
else if (chid_goto_idle)
|
next_cpu_state = CHG_CHID;
|
next_cpu_state = CHG_CHID;
|