/* processor.v - Connects the different modules comprising the processor This file is part of the 9086 project. Copyright (c) 2024 Efthymios Kritikos This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ `include "exec_state_def.v" `include "alu_header.v" `include "config.v" `include "error_header.v" //HALT: active high //IOMEM: 1=IO 0=MEM //BHE: active low //write: active low //read: active low //reset: active low module processor ( /* MISC */ input clock, input reset, output wire HALT,output [`ERROR_BITS-1:0] ERROR /* MEMORY / IO */ ,output [19:0] external_address_bus, input [15:0] external_data_bus_read, output [15:0] external_data_bus_write, input wait_state, output read, output write,output BHE,output IOMEM `ifdef CALCULATE_IPC /* STATISTICS */ ,output wire new_instruction `endif `ifdef OUTPUT_JSON_STATISTICS /* */ ,output wire [`L1_CACHE_SIZE-1:0] L1_SIZE_STAT, output wire VALID_INSTRUCTION_STAT, output wire jump_req_debug `endif ); `ifdef OUTPUT_JSON_STATISTICS assign jump_req_debug=biu_jump_req; `endif /* If there is an error either from the decoder or execution unit set it to ERROR */ assign ERROR=(DE_ERROR!=`ERR_NO_ERROR)?DE_ERROR:(EXEC_ERROR!=`ERR_NO_ERROR)?EXEC_ERROR:`ERR_NO_ERROR; /*############ Execution Unit ################################################### */ wire [`ERROR_BITS-1:0] EXEC_ERROR; wire biu_read_request,biu_jump_req,biu_write_request,use_exec_reg_addr; wire [3:0] EXEC_reg_read_port1_addr; wire [15:0] ALU_O; wire [7:0] EX2DE_FLAGS; wire [15:0] BIU_ADDRESS_INPUT; wire reg_write_we; wire next_exec; execute_unit execute_unit ( /***************** GENERAL *****************/ /* */ clock, reset, write, EXEC_ERROR /*************** INPUT FROM DE ***************/ /* SYNC SIGNALS */ ,valid_exec_data,set_initial_values /* INSTR. PARAMS */ ,Wbit, IN_MOD, OUT_MOD, RM /* DATA */ ,PARAM1_INIT,PARAM2_INIT,ProgCount /* STATE CONTROL */ ,next_state /* ALU CONTROL */ ,in_alu_sel1, in_alu_sel2, ALU_OP, ALU_O /* OTHER */ ,memio_address_select /**************** OUTPUT TO DE ****************/ /* SYNC SIGNALS */ ,next_exec /* FLAGS */ ,EX2DE_FLAGS /**************** OUTPUT TO BIU ****************/ /* */ ,BIU_ADDRESS_INPUT /* */ ,biu_read_request, biu_jump_req, biu_write_request /*************** INPUT FROM BIU ****************/ /* */ ,BIU_VALID_DATA,BIU_EX_DATA_READ /**************** OUTPUT TO BIU ****************/ /* */ ,BIU_EX_DATA_WRITE /***************** REGISTERS *****************/ /* */ ,reg_read_port1_data, reg_read_port2_data, EXEC_reg_read_port1_addr /* */ ,use_exec_reg_addr, reg_write_we ); /*############ Bus Interface Unit ############################################### */ wire [15:0] INSTRUCTION_LOCATION; wire [15:0] BIU_EX_DATA_READ,BIU_EX_DATA_WRITE; wire [31:0] IF2DE_INSTRUCTION; wire BIU_VALID_DATA; wire VALID_INSTRUCTION; BIU BIU( /***************** GENERAL *****************/ /* */ clock,reset /**************** OUTSIDE WORLD ****************/ /* */ ,external_address_bus /* */ ,external_data_bus_read,external_data_bus_write,read,write,BHE,IOMEM /* */ ,wait_state /**************** OUTPUT TO DE ****************/ /* */ ,IF2DE_INSTRUCTION,VALID_INSTRUCTION,INSTRUCTION_LOCATION /* */ ,BIU_VALID_DATA /**************** INPUT FROM DE ****************/ ,Wbit,MEM_OR_IO,VALID_INSTRUCTION_ACK /**************** INPUT FROM EX ****************/ /* */ ,biu_jump_req,biu_write_request,biu_read_request /* */ ,BIU_ADDRESS_INPUT,BIU_EX_DATA_WRITE /***************** OUTPUT TO EX ****************/ /* */ ,BIU_EX_DATA_READ `ifdef OUTPUT_JSON_STATISTICS /***************** STATISTICS *****************/ /* */ ,L1_SIZE_STAT, VALID_INSTRUCTION_STAT `endif ); /*############ Decoder ########################################################## */ wire [`ERROR_BITS-1:0] DE_ERROR; wire valid_exec_data, set_initial_values, Wbit; wire memio_address_select, MEM_OR_IO, VALID_INSTRUCTION_ACK; wire [1:0] in_alu_sel1, in_alu_sel2; wire [2:0] IN_MOD,OUT_MOD, RM; wire [3:0] DE_reg_read_port1_addr,DE_reg_read_port2_addr, reg_write_addr; wire [15:0] PARAM1_INIT, PARAM2_INIT, ProgCount; wire [`ALU_OP_BITS-1:0] ALU_OP; wire [`EXEC_STATE_BITS-1:0] next_state; decoder decoder( /***************** GENERAL *****************/ /* Input from sys. */ clock, reset /* Output to sys. */ ,MEM_OR_IO, DE_ERROR, HALT /*************** INPUT FROM IF ***************/ /* */ ,IF2DE_INSTRUCTION, VALID_INSTRUCTION /* */ ,INSTRUCTION_LOCATION /*************** OUTPUT TO IF ***************/ /* */ ,VALID_INSTRUCTION_ACK /*************** INPUT FROM EX ***************/ /* */ ,EX2DE_FLAGS[7:0], next_exec /*************** OUTPUT TO DE ***************/ /* SYNC SIGNALS */ ,set_initial_values, valid_exec_data /* INSTR. PARAMS */ ,Wbit, IN_MOD, OUT_MOD, RM /* DATA */ ,PARAM1_INIT, PARAM2_INIT, ProgCount /* STATE CONTROL */ ,next_state /* ALU CONTROL */ ,in_alu_sel1, in_alu_sel2, ALU_OP /* OTHER */ ,memio_address_select /************* OUTPUT TO REGISTERS ************/ /* */ , reg_write_addr,DE_reg_read_port2_addr, DE_reg_read_port1_addr `ifdef CALCULATE_IPC /* STATISTICS */ , new_instruction `endif ); /*############ Registers ######################################################## */ wire [3:0] reg_read_port1_addr; assign reg_read_port1_addr = use_exec_reg_addr ? EXEC_reg_read_port1_addr : DE_reg_read_port1_addr; wire [15:0] reg_read_port1_data, reg_read_port2_data; register_file register_file( /* WRITE */ .write_port1_addr(reg_write_addr), //TODO: should this come from exec instead? /* */ .write_port1_data(ALU_O), /* */ .write_port1_we(reg_write_we), /* READ 1 */ .read_port1_addr(reg_read_port1_addr), /* */ .read_port1_data(reg_read_port1_data), /* READ 2 */ .read_port2_addr(DE_reg_read_port2_addr), /* */ .read_port2_data(reg_read_port2_data), /* GENERAL */ .clock(clock) ); /*############################################################################### */ endmodule