Line 191... |
Line 191... |
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
|
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; // Signal 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
|
Line 216... |
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 || (start_thread);
|
//assign mem_access = data_access || load_next_inst || start_thread;
|
assign mem_access = data_access || load_next_inst || (cpu_state == CONT) ||
|
assign mem_access = data_access || load_next_inst || (cpu_state == CONT) ||
|
(cpu_state == BREAK_2) || (start_thread);
|
(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 320... |
Line 320... |
debug_active <= 1'b0;
|
debug_active <= 1'b0;
|
debug_edge <= 0;
|
debug_edge <= 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
debug_active <= !xgdbg_clear && ((xgdbg_set && mem_req_ack && (next_cpu_state == CONT)) || brk_set_dbg || op_code_error || debug_active);
|
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;
|
debug_edge <= debug_active;
|
end
|
end
|
|
|
assign debug_ack = debug_active && !debug_edge; // Posedge of debug_active
|
assign debug_ack = debug_active && !debug_edge; // Posedge of debug_active
|
|
|
Line 335... |
Line 336... |
else
|
else
|
xgss_edge <= xgss;
|
xgss_edge <= xgss;
|
|
|
assign single_step = (xgss && !xgss_edge) || (!debug_active && debug_edge);
|
assign single_step = (xgss && !xgss_edge) || (!debug_active && debug_edge);
|
|
|
|
wire stm_auto_advance;
|
|
assign stm_auto_advance = (chid_sm != CHID_IDLE);
|
|
// assign stm_auto_advance = (chid_sm != CHID_IDLE) || (!(load_next_inst || data_access));
|
|
|
// 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 || (chid_sm != CHID_IDLE)) ? next_cpu_state : cpu_state;
|
cpu_state <= (mem_req_ack || stm_auto_advance) ? 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 355... |
Line 359... |
// 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 <= (write_xgchid && debug_active) ? perif_data[6:0] : ((cpu_is_idle && mem_req_ack) ? int_req : xgchid);
|
xgchid <= (write_xgchid && debug_active) ? perif_data[6:0] : (cpu_is_idle ? int_req : xgchid);
|
|
|
// Channel Change Debug state machine register
|
// Channel Change Debug state machine 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 )
|
chid_sm <= CHID_IDLE;
|
chid_sm <= CHID_IDLE;
|
Line 401... |
Line 405... |
else
|
else
|
program_counter <= (|write_xgpc && perif_wrt_ena) ?
|
program_counter <= (|write_xgpc && perif_wrt_ena) ?
|
{(write_xgpc[1] ? perif_data[15:8]: program_counter[15:8]),
|
{(write_xgpc[1] ? perif_data[15:8]: program_counter[15:8]),
|
(write_xgpc[0] ? perif_data[ 7:0]: program_counter[ 7:0])} :
|
(write_xgpc[0] ? perif_data[ 7:0]: program_counter[ 7:0])} :
|
(mem_req_ack ? next_pc : program_counter);
|
(mem_req_ack ? next_pc : program_counter);
|
|
//((mem_req_ack || (cpu_state == BREAK_2)) ? next_pc : program_counter);
|
|
|
// 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;
|
Line 531... |
Line 536... |
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;
|
pc_incr_mux = 16'h0002; // Verilog Instruction order dependent
|
pc_incr_mux = (debug_active && xgdbg_set) ? 16'h0000: 16'h0002; // Verilog Instruction order dependent
|
next_pc = pc_sum; // ""
|
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;
|
Line 677... |
Line 682... |
|
|
// 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_LOAD, 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_LOAD, 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 2145... |
Line 2148... |
4'h7 : semap_risc_bit = 8'b1000_0000;
|
4'h7 : semap_risc_bit = 8'b1000_0000;
|
endcase
|
endcase
|
|
|
assign semaph_stat = |risc_semap;
|
assign semaph_stat = |risc_semap;
|
|
|
// A "generate" statment would be good here but it's not supported in iverilog
|
// Semaphore Bits
|
// Semaphore Bit
|
genvar sem_gen_count;
|
semaphore_bit semaphore_0(
|
generate
|
|
for (sem_gen_count = 0; sem_gen_count < 8; sem_gen_count = sem_gen_count + 1)
|
|
begin:semaphore_
|
|
semaphore_bit bit(
|
// outputs
|
// outputs
|
.host_status( host_semap[0] ),
|
.host_status( host_semap[sem_gen_count] ),
|
.risc_status( risc_semap[0] ),
|
.risc_status( risc_semap[sem_gen_count] ),
|
// inputs
|
// inputs
|
.risc_clk( risc_clk ),
|
.risc_clk( risc_clk ),
|
.async_rst_b( async_rst_b ),
|
.async_rst_b( async_rst_b ),
|
.risc_bit_sel( semap_risc_bit[0] ),
|
.risc_bit_sel( semap_risc_bit[sem_gen_count] ),
|
.csem( clear_semaph ),
|
.csem( clear_semaph ),
|
.ssem( set_semaph ),
|
.ssem( set_semaph ),
|
.host_wrt( write_xgsem ),
|
.host_wrt( write_xgsem ),
|
.host_bit_mask( perif_data[8] ),
|
.host_bit_mask( perif_data[sem_gen_count+8] ),
|
.host_bit( perif_data[0] )
|
.host_bit( perif_data[sem_gen_count] )
|
);
|
);
|
|
end
|
// Semaphore Bit
|
endgenerate
|
semaphore_bit semaphore_1(
|
|
// outputs
|
|
.host_status( host_semap[1] ),
|
|
.risc_status( risc_semap[1] ),
|
|
// inputs
|
|
.risc_clk( risc_clk ),
|
|
.async_rst_b( async_rst_b ),
|
|
.risc_bit_sel( semap_risc_bit[1] ),
|
|
.csem( clear_semaph ),
|
|
.ssem( set_semaph ),
|
|
.host_wrt( write_xgsem ),
|
|
.host_bit_mask( perif_data[9] ),
|
|
.host_bit( perif_data[1] )
|
|
);
|
|
|
|
// Semaphore Bit
|
|
semaphore_bit semaphore_2(
|
|
// outputs
|
|
.host_status( host_semap[2] ),
|
|
.risc_status( risc_semap[2] ),
|
|
// inputs
|
|
.risc_clk( risc_clk ),
|
|
.async_rst_b( async_rst_b ),
|
|
.risc_bit_sel( semap_risc_bit[2] ),
|
|
.csem( clear_semaph ),
|
|
.ssem( set_semaph ),
|
|
.host_wrt( write_xgsem ),
|
|
.host_bit_mask( perif_data[10] ),
|
|
.host_bit( perif_data[2] )
|
|
);
|
|
|
|
// Semaphore Bit
|
|
semaphore_bit semaphore_3(
|
|
// outputs
|
|
.host_status( host_semap[3] ),
|
|
.risc_status( risc_semap[3] ),
|
|
// inputs
|
|
.risc_clk( risc_clk ),
|
|
.async_rst_b( async_rst_b ),
|
|
.risc_bit_sel( semap_risc_bit[3] ),
|
|
.csem( clear_semaph ),
|
|
.ssem( set_semaph ),
|
|
.host_wrt( write_xgsem ),
|
|
.host_bit_mask( perif_data[11] ),
|
|
.host_bit( perif_data[2] )
|
|
);
|
|
|
|
// Semaphore Bit
|
|
semaphore_bit semaphore_4(
|
|
// outputs
|
|
.host_status( host_semap[4] ),
|
|
.risc_status( risc_semap[4] ),
|
|
// inputs
|
|
.risc_clk( risc_clk ),
|
|
.async_rst_b( async_rst_b ),
|
|
.risc_bit_sel( semap_risc_bit[4] ),
|
|
.csem( clear_semaph ),
|
|
.ssem( set_semaph ),
|
|
.host_wrt( write_xgsem ),
|
|
.host_bit_mask( perif_data[12] ),
|
|
.host_bit( perif_data[4] )
|
|
);
|
|
|
|
// Semaphore Bit
|
|
semaphore_bit semaphore_5(
|
|
// outputs
|
|
.host_status( host_semap[5] ),
|
|
.risc_status( risc_semap[5] ),
|
|
// inputs
|
|
.risc_clk( risc_clk ),
|
|
.async_rst_b( async_rst_b ),
|
|
.risc_bit_sel( semap_risc_bit[5] ),
|
|
.csem( clear_semaph ),
|
|
.ssem( set_semaph ),
|
|
.host_wrt( write_xgsem ),
|
|
.host_bit_mask( perif_data[13] ),
|
|
.host_bit( perif_data[5] )
|
|
);
|
|
|
|
// Semaphore Bit
|
|
semaphore_bit semaphore_6(
|
|
// outputs
|
|
.host_status( host_semap[6] ),
|
|
.risc_status( risc_semap[6] ),
|
|
// inputs
|
|
.risc_clk( risc_clk ),
|
|
.async_rst_b( async_rst_b ),
|
|
.risc_bit_sel( semap_risc_bit[6] ),
|
|
.csem( clear_semaph ),
|
|
.ssem( set_semaph ),
|
|
.host_wrt( write_xgsem ),
|
|
.host_bit_mask( perif_data[14] ),
|
|
.host_bit( perif_data[6] )
|
|
);
|
|
|
|
// Semaphore Bit
|
|
semaphore_bit semaphore_7(
|
|
// outputs
|
|
.host_status( host_semap[7] ),
|
|
.risc_status( risc_semap[7] ),
|
|
// inputs
|
|
.risc_clk( risc_clk ),
|
|
.async_rst_b( async_rst_b ),
|
|
.risc_bit_sel( semap_risc_bit[7] ),
|
|
.csem( clear_semaph ),
|
|
.ssem( set_semaph ),
|
|
.host_wrt( write_xgsem ),
|
|
.host_bit_mask( perif_data[15] ),
|
|
.host_bit( perif_data[7] )
|
|
);
|
|
|
|
|
|
endmodule // xgate_inst_decode
|
endmodule // xgate_inst_decode
|
|
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|