URL
https://opencores.org/ocsvn/forwardcom/forwardcom/trunk
Subversion Repositories forwardcom
[/] [forwardcom/] [trunk/] [top.sv] - Rev 137
Go to most recent revision | Compare with Previous | Blame | View Log
/******************************************************************************
* Engineer: Agner Fog
*
* Create date: 2020-05-03
* Last modified: 2021-08-05
* Module name: top
* Project name: ForwardCom soft core
* Tool versions: Vivado 2020.1
* License: CERN-OHL-W version 2 or later
* Description: Top level module of ForwardCom softcore
*
* The pipeline stages are connected here:
* 1. fetch: Fetch code words from code memory
* 2. decoder Decode instruction code
* 3. register_read Read registers. The register file is included in this stage
* 4. addressgenerator Calculate address of any memory operand
* 5. dataread Wait for data being read from data RAM
* 6a. alu Execute the instruction and calculate the result
* 6b. in_out_ports Input and output instructions etc. go here instead of into alu
*
* Other modules connected here:
* clock_generator: Controls the clock frequency of the global clock
* code_memory: Code memory or cache
* data_memory: Data memory or cache
* call_stack: Call stack for function return addresses
* debug_display: Shows contents of each pipeline stage on LCD display
* debugger.vh: Displays values of any signals anywhere in system on LED displays
*
******************************************************************************/
`include "defines.vh"
/*
Signals have name prefixes indicating the modules that generate them.
Handshaking signals between pipeline stages:
valid_in: Preceding stage has valid data ready
valid_out: Valid data are ready for next stage
stall_in: Keep your data for the next clock cycle
stall_out: Unable to receive new data
stall_predict_out: Predict that the next stage in pipeline will stall in next clock cycle
There is currently no contention for result buses, but future implementation may need handshaking for this:
result_bus_require_out: Needs result bus in next clock cycle
result_bus_acknowledge_in: No unit with higher privilege is taking the result bus
result_bus_enable_out: A result is on the result bus
*/
module top (
input clock100, // board input clock 100 MHz
input switch0, // switches for debug modes
input switch1, // switches for debug modes
input switch2, // switches for debug modes
input switch3, // switches for debug modes
input switch4, // switches for debug modes
input switch5, // switches for debug modes
input switch6, // switches for debug modes
input switch7, // switches for debug modes
input switch8, // switches for debug modes
input switch15, // disables error stop
input step_button, // Single stepping (RIGHT BUTTON)
input run_button, // Stop single stepping and start free running (UP BUTTON)
input reset_button, // Reset to start of program (DOWN BUTTON)
input load_button, // Load program throung serial interfase (!CPU RESET BUTTON)
input step_button_x, // Single stepping (external button)
input run_button_x, // Stop single stepping and start free running (external button)
input reset_button_x, // Reset to start of program (external button)
input load_button_x, // Loader (external button)
input external_connected_x, // high if external debug interface is connected
input debug1_switch, // enable single-stepping, pipeline mode
input debug2_switch, // enable single-stepping, instruction mode
input uart_txd_in, // UART transmit from PC
input uart_rts_in, // UART RTS from PC
output reg [7:0] segment7seg, // segment output, active low
output reg [7:0] digit7seg, // digit select output, active low
output reg [3:0] lcd_data, // data to LCD display
output reg lcd_rs, // control signal for LCD display
output reg [1:0] lcd_e, // enable signals for LCD displays
output uart_rxd_out, // UART receive to PC
output uart_cts_out, // UART CTS to PC
output led0, // use of led's: see below
output led1,
output led2,
output led3,
output led4,
output led5,
output led6,
output led7,
output led12,
output led13,
output led14,
output led15,
output led16R, // RGB led
output led16G,
output led16B
);
// generate clock (Xilinx specific. Generated by Clocking Wizard)
clock_generator clock_generator_inst (
.clk_in(clock100), // board input clock, 100 MHz
.clk_out(clock), // synthesized clock, frequency is `CLOCK_FREQUENCY
.locked() // clock frequency has stabilized
);
// control single stepping
reg single_step_mode;
reg step_button_debounced;
reg run_button_debounced;
reg reset_button_debounced;
reg load_button_debounced;
reg step_button_pulse;
reg run_button_pulse;
reg reset_button_pulse;
reg load_button_pulse;
reg [2:0] reset_step = 3'b111; // shift register for system reset clock cycles
reg clock_enable = 0;
reg system_reset = 1; // reset everything. load program
reg program_restart = 0; // restart loaded program
// pushbutton debouncers
// on-board buttons are always enabled, external buttons are enabled by external_connected_x
logic[3:0] input_buttons;
logic[3:0] debounced_buttons;
logic[3:0] button_pulse;
assign input_buttons[0] = step_button | (step_button_x & external_connected_x);
assign input_buttons[1] = run_button | (run_button_x & external_connected_x);
assign input_buttons[2] = reset_button | (reset_button_x & external_connected_x);
assign input_buttons[3] = (~load_button) | (load_button_x & external_connected_x);
assign debounced_buttons[0] = step_button_debounced;
assign debounced_buttons[1] = run_button_debounced;
assign debounced_buttons[2] = reset_button_debounced;
assign debounced_buttons[3] = load_button_debounced;
assign button_pulse[0] = step_button_pulse;
assign button_pulse[1] = run_button_pulse;
assign button_pulse[2] = reset_button_pulse;
assign button_pulse[3] = load_button_pulse;
debounce #(.num(4) ) debounce_inst
(.clock(clock),
.buttons_in (input_buttons),
.buttons_out(debounced_buttons),
.pulse_out(button_pulse));
/***************************************************
Signals connecting the stages
***************************************************/
// code memory
logic [`CODE_DATA_WIDTH-1:0] code_memory_data; // Data out
logic [31:0] code_memory_debug;
// data memory
logic [`RB1:0] data_memory_data;
// call stack
logic [`CODE_ADDR_WIDTH-1:0] call_stack_pop_data; // return address popped from call stack
logic call_stack_overflow; // call stack overflow or underflow or error
// register file input
logic [5:0] debug_reada; // read port for debugger
// signals from each pipeline stage
// fetch stage
logic fetch_valid;
logic fetch_jump; // jump instruction bypassing pipeline
logic fetch_call_e; // executing call instruction
logic fetch_return_e; // executing return instruction
logic [95:0] fetch_instruction;
logic [`CODE_ADDR_WIDTH-1:0] fetch_instruction_pointer; // point to current instruction
logic fetch_read_enable;
logic [`CODE_ADDR_WIDTH-2:0] fetch_read_addr; // Address for reading from code ram
logic [`CODE_ADDR_WIDTH-1:0] fetch_call_push_data; // return address pushed to call stack
logic [31:0] fetch_debug1; // temporary debug output
// decoder
logic [`TAG_WIDTH-1:0] decoder_tag_val; // instruction tag value
logic decoder_tag_write; // tag write enable
logic decoder_read; // read register enable
logic decoder_valid; // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] decoder_instruction_pointer; // address of current instruction
logic [95:0] decoder_instruction; // first word of instruction
logic decoder_stall; // Not ready to receive next instruction
logic [5:0] decoder_tag_a; // register number for instruction tag
logic decoder_vector; // this is a vector instruction
logic [1:0] decoder_category; // 00: multiformat, 01: single format, 10: jump
logic [1:0] decoder_format; // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [2:0] decoder_rs_status; // use of RS
logic [2:0] decoder_rt_status; // use of RT
logic [1:0] decoder_ru_status; // 1: RU is used
logic [1:0] decoder_rd_status; // 1: RD is used as input
logic [1:0] decoder_mask_status; // what the mask register is used for
logic decoder_mask_options; // 1: mask register may contain options
logic decoder_mask_alternative; // mask register and fallback register used for alternative purposes
logic [2:0] decoder_fallback_use; // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
logic [1:0] decoder_num_operands; // number of source operands
logic [1:0] decoder_result_type; // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0] decoder_offset_field; // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
logic [1:0] decoder_immediate_field; // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0] decoder_scale_factor; // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic decoder_index_limit; // index has a limit
logic [31:0] decoder_debug1; // temporary debug output
// register read stage
logic registerread_valid; // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] registerread_instruction_pointer; // address of current instruction
logic [95:0] registerread_instruction; // first word of instruction
logic registerread_stall_predict; // predict next stage will stall
logic [`TAG_WIDTH-1:0] registerread_tag_val; // instruction tag value
logic registerread_vector; // this is a vector instruction
logic [1:0] registerread_category; // 00: multiformat, 01: single format, 10: jump
logic [1:0] registerread_format; // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [1:0] registerread_num_operands; // number of source operands
logic [1:0] registerread_result_type; // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0] registerread_offset_field; // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
logic [1:0] registerread_immediate_field; // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0] registerread_scale_factor; // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic registerread_index_limit; // The field indicated by offset_field contains a limit to the index
logic [`RB:0] registerread_rd_val; // value of register operand RD, bit `RB indicates missing
logic [`RB:0] registerread_rs_val; // value of register operand RS, bit `RB indicates missing
logic [`RB:0] registerread_rt_val; // value of register operand RT, bit `RB indicates missing
logic [`RB:0] registerread_ru_val; // value of register operand RU, bit `RB indicates missing
logic [`MASKSZ:0] registerread_regmask_val; // value of mask register, bit 32 indicates missing
logic [1:0] registerread_rd_status; // RD is used as input
logic [2:0] registerread_rs_status; // use of RS
logic [2:0] registerread_rt_status; // use of RT
logic [1:0] registerread_ru_status; // RU is used
logic [1:0] registerread_mask_status; // mask register is used
logic registerread_mask_alternative; // mask register and fallback register used for alternative purposes
logic [2:0] registerread_fallback_use; // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
logic [32:0] registerread_debugport; // register read by debugger
// address generator
logic [`COMMON_ADDR_WIDTH-1:0] addrgen_read_write_address; // address of memory operand
logic addrgen_read_enable; // read from data memory
logic [1:0] addrgen_read_data_size;
logic [7:0] addrgen_write_enable;
logic [63:0] addrgen_write_data; // Any part of the 64 bits write bus can be used when the operand size is less than 64 bits
logic addrgen_valid; // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] addrgen_instruction_pointer; // address of current instruction
logic [63:0] addrgen_instruction; // first word of instruction
logic addrgen_stall_next; // address generator waiting for an operand
logic [`TAG_WIDTH-1:0] addrgen_tag_val; // instruction tag value
logic [`RB:0] addrgen_operand1; // value of first register operand
logic [`RB:0] addrgen_operand2; // value of second register operand
logic [`RB:0] addrgen_operand3; // value of last operand
logic [`MASKSZ:0] addrgen_regmask_val; // value of mask register, bit 32 indicates valid
logic addrgen_vector; // this is a vector instruction
logic [1:0] addrgen_category; // instruction category: multiformat, single format, jump
logic [1:0] addrgen_format; // instruction format: A, E, B, D
logic addrgen_mask_status; // mask register is used
logic addrgen_mask_alternative; // mask register and fallback register used for alternative purposes
logic [2:0] addrgen_fallback_use; // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
logic [1:0] addrgen_num_operands; // number of source operands
logic [1:0] addrgen_result_type; // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0] addrgen_offset_field; // unused
logic [1:0] addrgen_immediate_field; // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0] addrgen_scale_factor; // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic addrgen_memory_operand; // The instruction has a memory operand
logic addrgen_array_error; // Array index exceeds limit
logic [31:0] addrgen_debug1; // temporary debug output
logic [31:0] addrgen_debug2; // temporary debug output
logic [31:0] addrgen_debug3; // temporary debug output
// data read stage
logic dataread_valid; // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] dataread_instruction_pointer; // address of current instruction
logic [31:0] dataread_instruction; // first word of instruction
logic dataread_stall_predict; // predict next stage will stall
logic [`TAG_WIDTH-1:0] dataread_tag_val; // instruction tag value
logic [`RB:0] dataread_operand1; // value of first operand
logic [`RB:0] dataread_operand2; // value of second operand
logic [`RB:0] dataread_operand3; // value of last operand
logic [`MASKSZ:0] dataread_mask_val; // value of mask, bit 32 is 0 if valid
logic dataread_opr2_from_ram; // value of operand 2 comes from data memory
logic dataread_opr3_from_ram; // value of last operand comes from data memory
logic dataread_vector; // this is a vector instruction
logic [1:0] dataread_category; // 00: multiformat, 01: single format, 10: jump
logic [1:0] dataread_format; // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [1:0] dataread_num_operands; // number of source operands
logic dataread_opr1_used; // opr1_val_out is needed
logic dataread_opr2_used; // opr2_val_out is needed
logic dataread_opr3_used; // opr3_val_out is needed
logic dataread_regmask_used; // regmask_val_out is needed
logic dataread_mask_alternative; // mask register and fallback register used for alternative purposes
logic [1:0] dataread_result_type; // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [3:0] dataread_exe_unit; // each bit enables a particular execution unit
// 1: ALU, 10: MUL, 100: DIV, 1000: IN/OUT
logic [6:0] dataread_opx; // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
logic [5:0] dataread_opj; // operation ID for conditional jump instructions
logic [2:0] dataread_ot; // operand type
logic [5:0] dataread_option_bits; // option bits from IM3 or mask
logic [15:0] dataread_im2_bits; // constant bits from IM2 as extra operand
logic dataread_trap; // trap instruction detected. enable single step mode
logic dataread_array_error; // array index out of bounds
logic dataread_read_address_error; // invalid read memory address
logic dataread_write_address_error; // invalid write memory address
logic dataread_misaligned_address_error; // misaligned read/write memory address
logic [31:0] dataread_debug; // output for debugging
// alu stage
logic alu_valid; // for debug display: alu is active
logic alu_write_en; // write value to register file
logic [5:0] alu_register_a; // register to write
logic [`RB1:0] alu_result; // result to write
logic [`TAG_WIDTH-1:0] alu_tag; // instruction tag value
logic alu_jump; // jump instruction: jump taken
logic alu_nojump; // jump instruction: jump not taken
logic [`CODE_ADDR_WIDTH-1:0] alu_jump_pointer; // jump target to fetch unit
logic alu_stall;
logic alu_stall_next;
logic alu_error; // unknown instruction
logic alu_error_parm; // wrong parameter for instruction
logic [31:0] alu_debug1; // output for debugger
logic [31:0] alu_debug2; // output for debugger
// mul/div alu
logic muldiv_valid; // for debug display: alu is active
logic muldiv_write_en; // write value to register file
logic [4:0] muldiv_register_a; // register to write
logic [`RB1:0] muldiv_result; // result to write
logic [`TAG_WIDTH-1:0] muldiv_tag; // instruction tag value
logic muldiv_stall;
logic muldiv_stall_next;
logic muldiv_error; // unknown instruction
logic muldiv_error_parm; // wrong parameter for instruction
logic [31:0] muldiv_debug1; // output for debugger
logic [31:0] muldiv_debug2; // output for debugger
// in_out_ports
logic inout_valid; // for debug display: in_out is active
logic inout_write_en; // write value to register file
logic [5:0] inout_register_a; // register to write
logic [`RB1:0] inout_result; // result to write
logic [`TAG_WIDTH-1:0] inout_tag; // instruction tag value
logic inout_nojump; // serializing instruction read_perf gives jump not taken signal to resume pipeline
logic inout_stall;
logic inout_stall_next;
logic inout_error; // unknown instruction
logic inout_error_parm; // wrong parameter for instruction
logic [`N_ERROR_TYPES-1:0] inout_capab_disable_errors; // capab2 register: disable errors
logic [3:0] inout_first_error; // error type for first error, stored in inout module
logic [`CODE_ADDR_WIDTH-1:0] inout_first_error_address; // code address of first error
logic [31:0] inout_debug; // output for debugger
// error handling
logic [`N_ERROR_TYPES-1:0] errors_detect; // one bit for each type of error detected
logic clear_error; // clear error on debug display
reg show_error; // show error on debug display
/***************************************************
Top level logic signals
***************************************************/
// result bus 1
logic bus1_write_en; // write value to register file
logic [5:0] bus1_register_a; // register to write (includes system registers)
logic [`RB1:0] bus1_value; // value to write
logic [`TAG_WIDTH-1:0] bus1_tag; // result tag for value on bus 1
// result bus 2
logic bus2_write_en; // write value to register file
logic [4:0] bus2_register_a; // register to write
logic [`RB1:0] bus2_value; // value to write
logic [`TAG_WIDTH-1:0] bus2_tag; // result tag for value on bus 2
// signals for predicting when a result will be available
logic [`TAG_WIDTH-1:0] predict_tag1; // result tag value on bus 1 in next clock cycle
logic [`TAG_WIDTH-1:0] predict_tag2; // result tag value on bus 2 in next clock cycle
logic [`CODE_ADDR_WIDTH-2:0] code_read_addr; // Address for reading from ram
reg [2:0] color_led16; // RGB led
always_comb begin
// result bus 1
// There are no tri-state buffers inside the FPGA so we have to simulate the buses by OR'ing results:
bus1_write_en = alu_write_en | inout_write_en; // write value to register file
bus1_register_a = alu_register_a | inout_register_a; // register to write
bus1_value = alu_result | inout_result; // value to write
bus1_tag = alu_tag | inout_tag; // tag for result on bus 1
// result bus 2 not yet used
bus2_write_en = muldiv_write_en; // write value to register file
bus2_register_a = muldiv_register_a; // register to write
bus2_value = muldiv_result; // value to write
bus2_tag = muldiv_tag; // tag for result on bus 2
// read address for code memory. comes from fetch unit, except for taken conditional or indirect jumps/calls
code_read_addr = alu_jump ? (alu_jump_pointer >> 1) : fetch_read_addr;
// predict next tag on bus 1
predict_tag1 = (dataread_exe_unit[0] | dataread_exe_unit[3]) ? dataread_tag_val : 0;
// predict next tag on bus 2. To do: insert propagation delay !!
predict_tag2 = (dataread_exe_unit[1] | dataread_exe_unit[2]) ? dataread_tag_val : 0;
// error detection
errors_detect[0] = alu_error | muldiv_error | inout_error; // unknown instruction
errors_detect[1] = alu_error_parm | muldiv_error_parm | inout_error_parm | call_stack_overflow; // wrong parameter for instruction
errors_detect[2] = dataread_array_error; // array index out of bounds
errors_detect[3] = dataread_read_address_error; // read address violation
errors_detect[4] = dataread_write_address_error; // write address violation
errors_detect[5] = dataread_misaligned_address_error; // misaligned memory address
clear_error = reset_button_debounced | step_button_pulse | run_button_pulse | load_button_debounced; // clear error on debug display
end
// single step and reset control
always_ff @(posedge clock) begin
reset_step[2:0] <= {reset_step[1:0],(reset_button_debounced|load_button_debounced)}; // shift register delaying reset button
if (reset_button_debounced) begin
clock_enable <= 1; // enable clock while resetting
system_reset <= 1; // reset everything for 3 clock cycles
program_restart <= 1;
single_step_mode <= 0;
end else if (load_button_debounced) begin
clock_enable <= 1; // enable clock while resetting
system_reset <= 1; // reset everything for 3 clock cycles
program_restart <= 0;
single_step_mode <= 0;
end else if (reset_step != 0) begin
clock_enable <= 1; // enable clock while resetting
system_reset <= 1; // reset everything for 3 clock cycles
single_step_mode <= 0; // start in single step mode
end else if (single_step_mode) begin // single-stepping for debugging
clock_enable <= step_button_pulse; // enable for one clock cycle
system_reset <= 0;
program_restart <= 0;
end else begin // not single_step_mode
clock_enable <= 1;
system_reset <= 0;
program_restart <= 0;
end
// set or clear single step mode
if (run_button_pulse) single_step_mode <= 0;
if (step_button_pulse) single_step_mode <= 1;
if (dataread_trap) single_step_mode <= 1; // breakpoint sets single step mode
if (|(errors_detect & ~inout_capab_disable_errors) && !switch15) single_step_mode <= 1; // error detected
if (clear_error) show_error <= 0;
if (|(errors_detect & ~inout_capab_disable_errors)) show_error <= 1;
end
/***************************************************
Memory modules
***************************************************/
// code memory
code_memory code_memory_inst(
.clock(clock), // clock
.clock_enable(clock_enable),
.read_enable(fetch_read_enable | alu_jump), // read enable
.write_enable(addrgen_write_enable),
.write_addr_in(addrgen_read_write_address),
.write_data_in(addrgen_write_data), // Data in
.read_addr_in(code_read_addr), // Address for reading from code ram
.data_out(code_memory_data), // Data out
.debug_out(code_memory_debug)
);
// read/write data memory
data_memory data_memory_inst (
.clock(clock), // clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.read_write_addr(addrgen_read_write_address), // Address for reading from ram
.read_enable(addrgen_read_enable), // read enable
.read_data_size(addrgen_read_data_size),
.write_enable(addrgen_write_enable), // write enable for each byte separately
.write_data_in(addrgen_write_data),
.read_data_out(data_memory_data) // Data out
);
// call stack
call_stack call_stack_instance(
.clock(clock), // clock
.clock_enable(clock_enable), // clock enable
.reset(system_reset), // reset
.call_e(fetch_call_e), // Executing call instruction
.return_e(fetch_return_e), // Executing return instruction
.push_data(fetch_call_push_data), // Return address pushed at call instruction
.pop_data(call_stack_pop_data), // Return address popped at return instruction
.overflow(call_stack_overflow)); // stack overflow or underflow or error
/***************************************************
Pipeline stages
***************************************************/
// code fetch module
fetch fetch_inst(
.clock(clock), // system clock (100 MHz)
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.restart(program_restart), // restart loaded program
.valid_in(1), // data from code memory ready
.stall_in(registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.jump_in(alu_jump), // a jump target is coming from the ALU.
.nojump_in(alu_nojump | inout_nojump), // jump target is next instruction
.jump_pointer(alu_jump_pointer), // jump target from ALU. jump_pointer is also sent to the code memory
.read_data(code_memory_data), // data from code memory
.return_pop_data(call_stack_pop_data), // Return address popped here at return instruction
.read_addr_out(fetch_read_addr), // code read address relative to code memory start
.read_enable_out(fetch_read_enable), // code memory read enable
.valid_out(fetch_valid), // An instruction is ready for output to decoder
.jump_out(fetch_jump), // Jump instruction bypassing pipeline
.instruction_pointer_out(fetch_instruction_pointer), // address of current instruction
.instruction_out(fetch_instruction), // current instruction, up to 3 32-bit words long
.call_e_out(fetch_call_e), // Executing call instruction. push_data contains return address
.return_e_out(fetch_return_e), // Executing return instruction. return address is available in advance on pop_data
.stall_predict_out(), // predict stall in decoder
.call_push_data_out(fetch_call_push_data) , // Return address pushed here at call instruction
.debug1_out(fetch_debug1) // temporary debug output
);
decoder decoder_inst (
.clock(clock), // system clock (100 MHz)
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(fetch_valid), // data from fetch module ready
.stall_in(registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.instruction_pointer_in(fetch_inst.instruction_pointer_out), // address of current instruction
.instruction_in(fetch_instruction), // current instruction, up to 3 words long
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1(bus1_tag), // tag of result in bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2(bus2_tag), // tag of result in bus 2
.valid_out(decoder_valid), // An instruction is ready for output to next stage
.instruction_pointer_out(decoder_instruction_pointer), // address of current instruction
.instruction_out(decoder_instruction), // first word of instruction
.stall_out(decoder_stall), // Not ready to receive next instruction
.tag_a_out(decoder_tag_a), // register number for instruction tag
.tag_val_out(decoder_tag_val), // instruction tag value
.tag_write_out(decoder_tag_write), // instruction tag write enable
.vector_out(decoder_vector), // this is a vector instruction
.category_out(decoder_category), // 00: multiformat, 01: single format, 10: jump
.format_out(decoder_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.rs_status_out(decoder_rs_status), // use of RS
.rt_status_out(decoder_rt_status), // use of RT
.ru_status_out(decoder_ru_status), // 1: RU is used
.rd_status_out(decoder_rd_status), // 1: RD is used as input
.mask_status_out(decoder_mask_status), // What the mask register is used for
.mask_options_out(decoder_mask_options), // 1: mask register may contain options
.mask_alternative_out(decoder_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_out(decoder_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.num_operands_out(decoder_num_operands), // number of source operands
.result_type_out(decoder_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_out(decoder_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_out(decoder_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_out(decoder_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.index_limit_out(decoder_index_limit), // The field indicated by offset_field contains a limit to the index
.debug1_out(decoder_debug1) // temporary debug output
);
register_read register_read_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(decoder_valid), // data from fetch module ready
.stall_in(registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.instruction_pointer_in(decoder_instruction_pointer), // address of current instruction
.instruction_in(decoder_instruction), // current instruction, up to 3 words long
.tag_write_in(decoder_tag_write), // write tag
.tag_val_in(decoder_tag_val), // instruction tag value
.vector_in(decoder_vector), // this is a vector instruction
.category_in(decoder_category), // 00: multiformat, 01: single format, 10: jump
.format_in(decoder_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.rs_status_in(decoder_rs_status), // 1: RS is register operand
.rt_status_in(decoder_rt_status), // 1: RT is register operand
.ru_status_in(decoder_ru_status), // 1: RU is used
.rd_status_in(decoder_rd_status), // 1: RD is used as input
.mask_status_in(decoder_mask_status), // use of mask
.mask_options_in(decoder_mask_options), // 1: mask register may contain options
.mask_alternative_in(decoder_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_in(decoder_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.num_operands_in(decoder_num_operands), // number of source operands
.result_type_in(decoder_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_in(decoder_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_in(decoder_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_in(decoder_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.index_limit_in(decoder_index_limit), // The field indicated by offset_field contains a limit to the index
.writeport1(bus1_value), // result bus 1
.writea1(bus1_register_a), // address input for bus 1
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1(bus1_tag), // tag of result in bus 1
.writeport2(bus2_value), // result bus 2
.writea2(bus2_register_a), // address input for bus 2
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2(bus2_tag), // tag of result in bus 2
.debug_reada(debug_reada), // register read port for debugger
.valid_out(registerread_valid), // An instruction is ready for output to next stage
.instruction_pointer_out(registerread_instruction_pointer), // address of current instruction
.instruction_out(registerread_instruction), // first word of instruction
.stall_predict_out(registerread_stall_predict), // predict next stage will stall
.tag_val_out(registerread_tag_val), // instruction tag value
.vector_out(registerread_vector), // this is a vector instruction
.category_out(registerread_category), // 00: multiformat, 01: single format, 10: jump
.format_out(registerread_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.num_operands_out(registerread_num_operands), // number of source operands
.result_type_out(registerread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_out(registerread_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_out(registerread_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_out(registerread_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.index_limit_out(registerread_index_limit), // The field indicated by offset_field contains a limit to the index
.rd_val_out(registerread_rd_val), // value of register operand RD, bit `RB indicates missing
.rs_val_out(registerread_rs_val), // value of register operand RS, bit `RB indicates missing
.rt_val_out(registerread_rt_val), // value of register operand RT, bit `RB indicates missing
.ru_val_out(registerread_ru_val), // value of register operand RU, bit `RB indicates missing
.regmask_val_out(registerread_regmask_val), // value of mask register, bit 32 indicates missing
.rd_status_out(registerread_rd_status), // 1: RD is used as input
.rs_status_out(registerread_rs_status), // use of RS
.rt_status_out(registerread_rt_status), // use of RT
.ru_status_out(registerread_ru_status), // 1: RU is used
.mask_status_out(registerread_mask_status), // 1: mask register is used
.mask_alternative_out(registerread_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_out(registerread_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.debugport_out(registerread_debugport) // read for debugging purpose
);
addressgenerator addressgenerator_inst (
.clock(clock), // system clock (100 MHz)
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(registerread_valid), // data from fetch module ready
.stall_in(dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.instruction_pointer_in(registerread_instruction_pointer), // address of current instruction
.instruction_in(registerread_instruction), // current instruction, up to 3 words long
.tag_val_in(registerread_tag_val), // instruction tag value
.vector_in(registerread_vector), // this is a vector instruction
.category_in(registerread_category), // 00: multiformat, 01: single format, 10: jump
.format_in(registerread_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.rs_status_in(registerread_rs_status), // use of RS
.rt_status_in(registerread_rt_status), // use of RT
.ru_status_in(registerread_ru_status), // RU is used
.rd_status_in(registerread_rd_status), // RD is used as input
.mask_status_in(registerread_mask_status), // mask register used
.mask_alternative_in(registerread_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_in(registerread_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.num_operands_in(registerread_num_operands), // number of source operands
.result_type_in(registerread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_in(registerread_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_in(registerread_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_in(registerread_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.index_limit_in(registerread_index_limit), // The field indicated by offset_field contains a limit to the index
.rd_val_in(registerread_rd_val), // value of register operand RD, bit `RB indicates missing
.rs_val_in(registerread_rs_val), // value of register operand RS, bit `RB indicates missing
.rt_val_in(registerread_rt_val), // value of register operand RT, bit `RB indicates missing
.ru_val_in(registerread_ru_val), // value of register operand RU, bit `RB indicates missing
.regmask_val_in(registerread_regmask_val), // mask register
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // tag on result bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // tag on result bus 2 in next clock cycle
.read_write_address_out(addrgen_read_write_address), // address of read memory operand
.read_enable_out(addrgen_read_enable), // enable read from data memory
.read_data_size_out(addrgen_read_data_size), // data size for memory read
.write_enable_out(addrgen_write_enable), // write enable for each byte separately
.write_data_out(addrgen_write_data), // data to write
.valid_out(addrgen_valid), // An instruction is ready for output to next stage
.instruction_pointer_out(addrgen_instruction_pointer), // address of current instruction
.instruction_out(addrgen_instruction), // first word of instruction
.stall_predict_out(addrgen_stall_next), // will be waiting for an operand
.tag_val_out(addrgen_tag_val), // instruction tag value
.operand1_out(addrgen_operand1), // value of first operand, bit `RB indicates invalid
.operand2_out(addrgen_operand2), // value of second operand, bit `RB indicates invalid
.operand3_out(addrgen_operand3), // value of last, bit `RB indicates valid
.regmask_val_out(addrgen_regmask_val), // value of mask register, bit 32 indicates valid
.vector_out(addrgen_vector), // this is a vector instruction
.category_out(addrgen_category), // 00: multiformat, 01: single format, 10: jump
.format_out(addrgen_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.mask_status_out(addrgen_mask_status), // 1: mask register used
.mask_alternative_out(addrgen_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_out(addrgen_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.num_operands_out(addrgen_num_operands), // number of source operands
.result_type_out(addrgen_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_out(addrgen_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_out(addrgen_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_out(addrgen_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.memory_operand_out(addrgen_memory_operand), // The instruction has a memory operand
.array_error_out(addrgen_array_error), // Array index exceeds limit
.options3_out(addrgen_options3), // IM3 containts option bits
.debug1_out(addrgen_debug1), // Temporary output for debugging purpose
.debug2_out(addrgen_debug2), // Temporary output for debugging purpose
.debug3_out(addrgen_debug3) // Temporary output for debugging purpose
);
dataread dataread_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(addrgen_valid), // data from fetch module ready
.stall_in(dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.instruction_pointer_in(addrgen_instruction_pointer), // address of current instruction
.instruction_in(addrgen_instruction), // current instruction, up to 3 words long
.tag_val_in(addrgen_tag_val), // instruction tag value
.vector_in(addrgen_vector), // this is a vector instruction
.category_in(addrgen_category), // 00: multiformat, 01: single format, 10: jump
.format_in(addrgen_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.mask_status_in(addrgen_mask_status), // 1: mask register used
.mask_alternative_in(addrgen_mask_alternative), // mask register and fallback register used for alternative purposes
.num_operands_in(addrgen_num_operands), // number of source operands
.result_type_in(addrgen_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.immediate_field_in(addrgen_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.memory_operand_in(addrgen_memory_operand), // the instruction has a memory operand
.array_error_in(addrgen_array_error), // Array index exceeds limit
.options3_in(addrgen_options3), // IM3 containts option bits
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // result tag value on bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // result tag value on bus 2 in next clock cycle
.operand1_in(addrgen_operand1), // value of first operand
.operand2_in(addrgen_operand2), // value of second operand
.operand3_in(addrgen_operand3), // value of last operand
.regmask_val_in(addrgen_regmask_val), // mask register
.address_in(addrgen_read_write_address), // address of memory operand
.ram_data_in(data_memory_data), // memory operand from data memory
.valid_out(dataread_valid), // An instruction is ready for output to next stage
.instruction_pointer_out(dataread_instruction_pointer),// address of current instruction
.instruction_out(dataread_instruction), // first word of instruction
.stall_predict_out(dataread_stall_predict), // predict next stage will stall
.tag_val_out(dataread_tag_val), // instruction tag value
.operand1_out(dataread_operand1), // value of first operand for 3-op instructions, bit `RB is 0 if valid
.operand2_out(dataread_operand2), // value of second operand, bit `RB is 0 if valid
.operand3_out(dataread_operand3), // value of last operand, bit `RB is 0 if valid
.mask_val_out(dataread_mask_val), // value of mask, bit 32 is 0 if valid
.opr2_from_ram_out(dataread_opr2_from_ram), // value of operand 2 comes from data memory
.opr3_from_ram_out(dataread_opr3_from_ram), // value of last operand comes from data memory
.vector_out(dataread_vector), // this is a vector instruction
.category_out(dataread_category), // 00: multiformat, 01: single format, 10: jump
.format_out(dataread_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.num_operands_out(dataread_num_operands), // number of source operands
.result_type_out(dataread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.opr1_used_out(dataread_opr1_used), // operand1 is needed
.opr2_used_out(dataread_opr2_used), // operand2 is needed
.opr3_used_out(dataread_opr3_used), // operand3 is needed
.regmask_used_out(dataread_regmask_used), // regmask_val_out is needed
.mask_alternative_out(dataread_mask_alternative), // mask register and fallback register used for alternative purposes
.exe_unit_out(dataread_exe_unit), // each bit enables a particular execution unit
.opx_out(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.opj_out(dataread_opj), // operation ID for conditional jump instructions
.ot_out(dataread_ot), // operand type
.option_bits_out(dataread_option_bits), // instruction option bits
.im2_bits_out(dataread_im2_bits), // constant bits from IM2 as extra operand
.trap_out(dataread_trap), // trap instruction detected
.array_error_out(dataread_array_error), // array index out of bounds
.read_address_error_out(dataread_read_address_error), // invalid read memory address
.write_address_error_out(dataread_write_address_error),// invalid write memory address
.misaligned_address_error_out(dataread_misaligned_address_error), // misaligned read/write memory address
.debug_out(dataread_debug) // output for debugging
);
alu alu_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(dataread_valid & dataread_exe_unit[0]), // data from previous stage ready
.stall_in(alu_stall_next | muldiv_stall_next | inout_stall_next),// pipeline is stalled
.instruction_pointer_in(dataread_instruction_pointer), // address of current instruction
.instruction_in(dataread_instruction), // current instruction, first word only
.tag_val_in(dataread_tag_val), // instruction tag value
.category_in(dataread_category), // 00: multiformat, 01: single format, 10: jump
.mask_alternative_in(dataread_mask_alternative), // mask register and fallback register used for alternative purposes
.result_type_in(dataread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.vector_in(dataread_vector), // vector instruction
.opx_in(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.opj_in(dataread_opj), // operation ID for conditional jump instructions
.ot_in(dataread_ot), // operand type
.option_bits_in(dataread_option_bits), // option bits from IM3 or mask
.im2_bits_in(dataread_im2_bits), // constant bits from IM2 as extra operand
// monitor result buses:
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // result tag value on bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // result tag value on bus 2 in next clock cycle
// Register values sampled from result bus in previous stages
.operand1_in(dataread_operand1), // first operand or fallback value
.operand2_in(dataread_operand2), // second operand value
.operand3_in(dataread_operand3), // last operand value
.regmask_val_in(dataread_mask_val), // mask register
.ram_data_in(data_memory_data), // memory operand from data memory
.opr2_from_ram_in(dataread_opr2_from_ram), // value of operand 2 comes from data memory
.opr3_from_ram_in(dataread_opr3_from_ram), // value of last operand comes from data memory
.opr1_used_in(dataread_opr1_used), // opr1_val_in is needed
.opr2_used_in(dataread_opr2_used), // opr2_val_in is needed
.opr3_used_in(dataread_opr3_used), // opr3_val_in is needed
.regmask_used_in(dataread_regmask_used), // regmask_val_in is needed
.valid_out(alu_valid), // alu is active
.register_write_out(alu_write_en), // write enable for bus 1
.register_a_out(alu_register_a), // register to write
.result_out(alu_result), //
.tag_val_out(alu_tag), // instruction tag value
.jump_out(alu_jump), // jump instruction: jump taken
.nojump_out(alu_nojump), // jump instruction: jump not taken
.jump_pointer_out(alu_jump_pointer), // jump target to fetch unit
.stall_out(alu_stall), // alu is waiting for an operand or not ready to receive a new instruction
.stall_next_out(alu_stall_next), // alu will be waiting in next clock cycle
.error_out(alu_error), // unknown instruction
.error_parm_out(alu_error_parm), // wrong parameter for instruction
.debug1_out(alu_debug1), // debug information
.debug2_out(alu_debug2) // debug information
);
mul_div muldiv_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(dataread_valid & (dataread_exe_unit[1] | dataread_exe_unit[2])), // data from previous stage ready
.stall_in(alu_stall_next | muldiv_stall_next | inout_stall_next),// pipeline is stalled
.instruction_in(dataread_instruction[31:0]), // current instruction, up to 3 words long
.tag_val_in(dataread_tag_val), // instruction tag value
.category_in(dataread_category), // 00: multiformat, 01: single format, 10: jump
.mask_alternative_in(dataread_mask_alternative), // mask register and fallback register used for alternative purposes
.result_type_in(dataread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.vector_in(dataread_vector), // vector instruction
.opx_in(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.ot_in(dataread_ot), // operand type
.option_bits_in(dataread_option_bits), // option bits from IM3 or mask
// monitor result buses:
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // result tag value on bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // result tag value on bus 2 in next clock cycle
// Register values sampled from result bus in previous stages
.operand1_in(dataread_operand1), // first operand or fallback value
.operand2_in(dataread_operand2), // second operand value
.operand3_in(dataread_operand3), // last operand value
.regmask_val_in(dataread_mask_val), // mask register
.ram_data_in(data_memory_data), // memory operand from data memory
.opr2_from_ram_in(dataread_opr2_from_ram), // value of operand 2 comes from data memory
.opr3_from_ram_in(dataread_opr3_from_ram), // value of last operand comes from data memory
.opr1_used_in(dataread_opr1_used), // opr1_val_in is needed
.opr2_used_in(dataread_opr2_used), // opr2_val_in is needed
.opr3_used_in(dataread_opr3_used), // opr3_val_in is needed
.regmask_used_in(dataread_regmask_used), // regmask_val_in is needed
.valid_out(muldiv_valid), // alu is active
.register_write_out(muldiv_write_en), // write enable for bus 1
.register_a_out(muldiv_register_a), // register to write
.result_out(muldiv_result), //
.tag_val_out(muldiv_tag), // instruction tag value
.stall_out(muldiv_stall), // alu is waiting for an operand or not ready to receive a new instruction
.stall_next_out(muldiv_stall_next), // alu will be waiting in next clock cycle
.error_out(muldiv_error), // unknown instruction
.error_parm_out(muldiv_error_parm), // wrong parameter for instruction
.debug1_out(muldiv_debug1), // debug information
.debug2_out(muldiv_debug2) // debug information
);
/***************************************************
Input and output ports
***************************************************/
in_out_ports in_out_ports_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset
.valid_in(dataread_valid & dataread_exe_unit[3]), // data from previous stage ready
.stall_in(alu_stall_next | muldiv_stall_next | inout_stall_next),// pipeline is stalled
.instruction_in(dataread_instruction[31:0]), // current instruction, up to 3 words long
.tag_val_in(dataread_tag_val), // instruction tag value
.category_in(dataread_category), // 00: multiformat, 01: single format, 10: jump
.result_type_in(dataread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.mask_alternative_in(dataread_mask_alternative), // mask register and fallback register used for alternative purposes
.vector_in(dataread_vector), // vector instruction
.opx_in(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.opj_in(dataread_opj), // operation ID for conditional jump instructions
.ot_in(dataread_ot), // operand type
.regmask_used_in(dataread_regmask_used), // regmask_val_in is needed
// connections to UART
.uart_bit_in(uart_txd_in), // serial input
.uart_rts_in(uart_rts_in), // ready to send input
// monitor result buses:
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // result tag value on bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // result tag value on bus 2 in next clock cycle
// Register values sampled from result bus in previous stages
.operand1_in(dataread_operand1), // first operand or fallback value
.operand2_in(dataread_operand2), // second operand
.operand3_in(dataread_operand3), // last operand
.regmask_val_in(dataread_mask_val), // mask register
.opr1_used_in(dataread_opr1_used), // opr1_val_in is needed
// signals used for performance monitoring
.instruction_valid_in(dataread_valid), // instruction is valid but possibly going to a different exe unit
.fast_jump_in(fetch_jump), // a jump is bypassing the pipeline
.errors_detect_in(errors_detect), // one bit for each type of error detected
.fetch_instruction_pointer(fetch_instruction_pointer),
.dataread_instruction_pointer(dataread_instruction_pointer),
.dataread_valid(dataread_valid), // used when reconstructing alu_instruction_pointer
.call_stack_overflow(call_stack_overflow), // used for differentiating errors_detect_in[1]
.clear_error_in(clear_error), // debug clear error
// outputs
.valid_out(inout_valid), // in_out is active
.register_write_out(inout_write_en),
.register_a_out(inout_register_a), // register to write
.result_out(inout_result),
.tag_val_out(inout_tag), // instruction tag value
.nojump_out(inout_nojump), // serializing instruction finished
.stall_out(inout_stal), // alu is waiting for an operand or not ready to receive a new instruction
.stall_next_out(inout_stall_next), // alu will be waiting in next clock cycle
.error_out(inout_error), // unknown instruction
.error_parm_out(inout_error_parm), // wrong parameter for instruction
.uart_bit_out(uart_rxd_out), // serial output
.uart_cts_out(uart_cts_out), // clear to send output
.capab_disable_errors(inout_capab_disable_errors), // capab2 register: disable errors
.first_error(inout_first_error), // error type for first error
.first_error_address(inout_first_error_address), // code address of first error
.debug_out(inout_debug) // debug information
);
/***************************************************
Debugging signals
***************************************************/
// debug display
debug_display debug_display_inst (
.clock(clock), // system clock (50 - 100 MHz)
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset_button_debounced(reset_button_debounced), // reset button
// from fetch stage
.fetch_instruction(fetch_instruction[63:0]), // first words of instruction
.fetch_instruction_pointer(fetch_instruction_pointer), // point to current instruction
.fetch_valid(fetch_valid), // output from fetch is ready
.fetch_jump(fetch_jump), // jump instruction bypassing pipeline
.fetch_call_e(fetch_call_e), // executing call instruction
.fetch_return_e(fetch_return_e), // executing return instruction
.registerread_stall_predict(registerread_stall_predict),// address generation stalled next
.addrgen_stall_next(addrgen_stall_next),
.dataread_stall_predict(dataread_stall_predict), // alu stalled next
.alu_stall_next(alu_stall_next), // alu stalled next
.muldiv_stall_next(muldiv_stall_next), // muldiv stalled next
.inout_stall_next(inout_stall_next), // in_out_ports stalled next
// from decoder
.decoder_instruction(decoder_instruction[63:0]), // first words of instruction
.decoder_instruction_pointer(decoder_instruction_pointer), // address of current instruction
.decoder_valid(decoder_valid), // output from decoder is ready
// from register_read
.registerread_instruction(registerread_instruction[63:0]), // first words of instruction
.registerread_instruction_pointer(registerread_instruction_pointer), // address of current instruction
.registerread_valid(registerread_valid), // output from decode_wait is ready
// from address generator
.addrgen_instruction(addrgen_instruction[63:0]), // first words of instruction
.addrgen_instruction_pointer(addrgen_instruction_pointer), // address of current instruction
.addrgen_valid(addrgen_valid), // output from addrgen is ready
// from address_wait
.dataread_instruction(dataread_instruction), // first words of instruction
.dataread_instruction_pointer(dataread_instruction_pointer), // address of current instruction
.dataread_opx(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.dataread_valid(dataread_valid), // output from addrwait is ready
.dataread_operand1(dataread_operand1), // first register operand RD or RU
.dataread_operand2(dataread_operand2), // second register operand RS
.dataread_operand3(dataread_operand3), // last register operand RT
.dataread_mask_val(dataread_mask_val), // mask register value
.ram_data_in(data_memory_data[15:0]), // memory operand from data memory
.dataread_opr2_from_ram(dataread_opr2_from_ram), // value of operand 2 comes from data ram
.dataread_opr3_from_ram(dataread_opr3_from_ram), // value of last operand comes from data ram
// from ALU
//.writea1(bus1_register_a), // register to write
.alu_result(bus1_value[31:0]), //
.write_tag1(bus1_tag),
.alu_valid(alu_valid | muldiv_valid | inout_valid), // alu or in_out is ready
.alu_jump(alu_jump), // jump instruction: jump taken
//.alu_nojump(alu_nojump), // jump instruction: jump not taken
.alu_jump_pointer(alu_jump_pointer),
// from result buses
.writeport2(bus2_value[31:0]),
.write_en2(bus2_write_en),
.write_tag2(bus2_tag),
// output to display
.lcd_rs(lcd_rs), // LCD RS pin
.lcd_e(lcd_e), // enable pins for two LCD displays
.lcd_data(lcd_data) // LCD data, 4 bit bus
);
`include "debugger.vh"
assign led0 = load_button_debounced;
assign led1 = reset_button_debounced;
assign led2 = run_button_debounced;
assign led3 = step_button_debounced;
assign led4 = fetch_call_e; // vacant. connected to something just to avoid warning
assign led5 = fetch_return_e;
assign led6 = fetch_valid;
assign led7 = system_reset;
/*
assign led12 = registerread_stall_predict;
assign led13 = addrgen_stall_next;
assign led14 = dataread_stall_predict;
assign led15 = alu_stall_next;
*/
// temporary led assignments
assign led12 = call_stack_overflow;
assign led13 = alu_error_parm | muldiv_error_parm;
assign led14 = inout_error_parm;
assign led15 = show_error;
// RGB led
assign led16R = color_led16[0];
assign led16G = color_led16[1];
assign led16B = color_led16[2];
endmodule
Go to most recent revision | Compare with Previous | Blame | View Log