Fixed copyright notices, did some major cleanup and bumped README's versions
This commit is contained in:
parent
a8ab6b2dc7
commit
539fb8416b
@ -19,11 +19,11 @@ A CPU that aims to be binary compatible with the 8086 and with as many optimisat
|
|||||||
Both Verilator and Icarus Verilog can be used for simulation. You can select which one you want with the SIM variable on [common.mk](./common.mk)
|
Both Verilator and Icarus Verilog can be used for simulation. You can select which one you want with the SIM variable on [common.mk](./common.mk)
|
||||||
Specifically this list shows the software needed and the versions used during development (other versions should work as well)
|
Specifically this list shows the software needed and the versions used during development (other versions should work as well)
|
||||||
|
|
||||||
* Icarus Verilog : version 11.0 OR **(preferred)** Verilator : 5.006
|
* Icarus Verilog : version 11.0 OR **(preferred)** Verilator : 5.008
|
||||||
* bin86 : 0.16.21
|
* bin86 : 0.16.21
|
||||||
* GNU Make : 4.4.1
|
* GNU Make : 4.4.1
|
||||||
* xxd : 2022-01-14
|
* xxd : 2022-01-14
|
||||||
* POSIX coreutils : GNU coreutils 9.1
|
* POSIX coreutils : GNU coreutils 9.3
|
||||||
|
|
||||||
After that you can run `make` on the top level directory and it should build everything and start the simulation
|
After that you can run `make` on the top level directory and it should build everything and start the simulation
|
||||||
|
|
||||||
|
86
system/biu.v
86
system/biu.v
@ -1,4 +1,4 @@
|
|||||||
/* processor.v - implementation of the 9086 bus interface unit. The logic that
|
/* biu.v - implementation of the 9086 bus interface unit. The logic that
|
||||||
controls all external bus functions
|
controls all external bus functions
|
||||||
|
|
||||||
This file is part of the 9086 project.
|
This file is part of the 9086 project.
|
||||||
@ -18,7 +18,7 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
//IOMEM: 1=IO 0=MEM
|
`include "config.v"
|
||||||
|
|
||||||
`define BIU_HALT 4'b0000
|
`define BIU_HALT 4'b0000
|
||||||
`define BIU_NEXT_ACTION 4'b0001
|
`define BIU_NEXT_ACTION 4'b0001
|
||||||
@ -38,9 +38,9 @@
|
|||||||
`define BIU_GET_SECOND_BYTE1 4'b1110
|
`define BIU_GET_SECOND_BYTE1 4'b1110
|
||||||
|
|
||||||
module BIU (
|
module BIU (
|
||||||
/*outside world*/ input clock, input reset, output reg [19:0] external_address_bus,
|
/* Outside world */ input clock, input reset, output reg [19:0] external_address_bus,
|
||||||
/* */ inout [15:0] external_data_bus,output reg read, output reg write,output reg BHE,output reg IOMEM,
|
/* */ inout [15:0] external_data_bus,output reg read, output reg write,output reg BHE,output reg IOMEM,
|
||||||
/* internal */ output reg [31:0] INSTRUCTION, output reg VALID_INSTRUCTION, output reg [15:0] INSTRUCTION_LOCATION, input jump_req,
|
/* Internal */ output reg [31:0] INSTRUCTION, output reg VALID_INSTRUCTION, output reg [15:0] INSTRUCTION_LOCATION, input jump_req,
|
||||||
/* */ input[15:0] ADDRESS_INPUT, inout [15:0] DATA, input write_request, input read_request, input Wbit, output reg VALID_DATA, input MEM_OR_IO,
|
/* */ input[15:0] ADDRESS_INPUT, inout [15:0] DATA, input write_request, input read_request, input Wbit, output reg VALID_DATA, input MEM_OR_IO,
|
||||||
/* */ input [`PROC_STATE_BITS-1:0] proc_state, input SIMPLE_MICRO
|
/* */ input [`PROC_STATE_BITS-1:0] proc_state, input SIMPLE_MICRO
|
||||||
);
|
);
|
||||||
@ -52,9 +52,8 @@ reg [15:0] DATA_OUT;
|
|||||||
reg DATA_DIR;
|
reg DATA_DIR;
|
||||||
assign DATA=DATA_DIR ? 16'hz:DATA_OUT;
|
assign DATA=DATA_DIR ? 16'hz:DATA_OUT;
|
||||||
|
|
||||||
`define L1_CACHE_SIZE 4 // Don't change this! some parts of the code assume this
|
`define FIFO_SIZE_BYTES $rtoi($pow(2,`L1_CACHE_SIZE))
|
||||||
|
|
||||||
`define FIFO_SIZE_BYTES 16 //$pow(2,`L1_CACHE_SIZE)
|
|
||||||
reg [7:0] INPUT_FIFO [`FIFO_SIZE_BYTES-1:0];
|
reg [7:0] INPUT_FIFO [`FIFO_SIZE_BYTES-1:0];
|
||||||
reg [`L1_CACHE_SIZE-1:0] FIFO_start; /*inclusive*/
|
reg [`L1_CACHE_SIZE-1:0] FIFO_start; /*inclusive*/
|
||||||
reg [`L1_CACHE_SIZE-1:0] FIFO_end; /*exclusive*/
|
reg [`L1_CACHE_SIZE-1:0] FIFO_end; /*exclusive*/
|
||||||
@ -65,7 +64,6 @@ reg [3:0] biu_state;
|
|||||||
always @(negedge reset) begin
|
always @(negedge reset) begin
|
||||||
biu_state <= `BIU_HALT;
|
biu_state <= `BIU_HALT;
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge reset) begin
|
always @(posedge reset) begin
|
||||||
biu_state <= `BIU_RESET;
|
biu_state <= `BIU_RESET;
|
||||||
end
|
end
|
||||||
@ -76,10 +74,8 @@ reg func;
|
|||||||
reg [19:0]INSTRUCTION_ADDRESS;
|
reg [19:0]INSTRUCTION_ADDRESS;
|
||||||
reg [19:0]DATA_ADDRESS;
|
reg [19:0]DATA_ADDRESS;
|
||||||
|
|
||||||
|
|
||||||
assign external_address_bus= func? INSTRUCTION_ADDRESS : DATA_ADDRESS ;
|
assign external_address_bus= func? INSTRUCTION_ADDRESS : DATA_ADDRESS ;
|
||||||
|
|
||||||
/* Read into the FIFO */
|
|
||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
if ( jump_req_latch ) begin
|
if ( jump_req_latch ) begin
|
||||||
/* verilator lint_off BLKSEQ */
|
/* verilator lint_off BLKSEQ */
|
||||||
@ -145,33 +141,30 @@ always @(posedge clock) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
/*************** INSTRUCTION FIFO READ ***************/
|
/*************** INSTRUCTION FIFO READ ***************/
|
||||||
`BIU_READ: begin
|
`BIU_READ: begin
|
||||||
/* verilator lint_off BLKSEQ */
|
|
||||||
if(INSTRUCTION_ADDRESS[0:0]==0 && FIFO_SIZE<4'hD)begin
|
if(INSTRUCTION_ADDRESS[0:0]==0 && FIFO_SIZE<4'hD)begin
|
||||||
INPUT_FIFO[FIFO_end] = external_data_bus[7:0];
|
INPUT_FIFO[FIFO_end] <= external_data_bus[7:0];
|
||||||
INPUT_FIFO[FIFO_end+4'd1] = external_data_bus[15:8];
|
INPUT_FIFO[FIFO_end+4'd1] <= external_data_bus[15:8];
|
||||||
FIFO_end <= FIFO_end+4'd2;
|
FIFO_end <= FIFO_end+4'd2;
|
||||||
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+20'd2;
|
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+20'd2;
|
||||||
end else if(INSTRUCTION_ADDRESS[0:0]==0)begin
|
end else if(INSTRUCTION_ADDRESS[0:0]==0)begin
|
||||||
INPUT_FIFO[FIFO_end] = external_data_bus[7:0];
|
INPUT_FIFO[FIFO_end] <= external_data_bus[7:0];
|
||||||
FIFO_end <= FIFO_end+4'd1;
|
FIFO_end <= FIFO_end+4'd1;
|
||||||
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
|
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
|
||||||
end else begin
|
end else begin
|
||||||
INPUT_FIFO[FIFO_end] = external_data_bus[15:8];
|
INPUT_FIFO[FIFO_end] <= external_data_bus[15:8];
|
||||||
FIFO_end <= FIFO_end+4'd1;
|
FIFO_end <= FIFO_end+4'd1;
|
||||||
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
|
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
|
||||||
end
|
end
|
||||||
/* verilator lint_on BLKSEQ */
|
|
||||||
biu_state <= `BIU_NEXT_ACTION;
|
biu_state <= `BIU_NEXT_ACTION;
|
||||||
read<=1;
|
read<=1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
/*************** DATA WRITE ***************/
|
/*************** DATA WRITE ***************/
|
||||||
//TODO TODO TODO flush fifo, self modifying code
|
//TODO TODO TODO flush fifo, self modifying code
|
||||||
`BIU_PUT_UNALIGNED_16BIT_DATA:begin
|
`BIU_PUT_UNALIGNED_16BIT_DATA:begin
|
||||||
//TODO Put that in the previous stage, save a clock cycle
|
|
||||||
`ifdef DEBUG_DATA_READ_WRITES
|
`ifdef DEBUG_DATA_READ_WRITES
|
||||||
$display("Writing 16bit %04x at %04x",DATA,DATA_ADDRESS);
|
$display("Writing 16bit %04x at %04x",DATA,DATA_ADDRESS);
|
||||||
`endif
|
`endif
|
||||||
@ -194,7 +187,6 @@ always @(posedge clock) begin
|
|||||||
write <= 0;
|
write <= 0;
|
||||||
biu_state <= `BIU_WRITE_RELEASE;
|
biu_state <= `BIU_WRITE_RELEASE;
|
||||||
end
|
end
|
||||||
|
|
||||||
`BIU_PUT_BYTE:begin
|
`BIU_PUT_BYTE:begin
|
||||||
`ifdef DEBUG_DATA_READ_WRITES
|
`ifdef DEBUG_DATA_READ_WRITES
|
||||||
$display("Writing 8bit %02x at %04x",DATA[7:0],DATA_ADDRESS);
|
$display("Writing 8bit %02x at %04x",DATA[7:0],DATA_ADDRESS);
|
||||||
@ -288,10 +280,9 @@ end
|
|||||||
|
|
||||||
wire [2:0] Isize;
|
wire [2:0] Isize;
|
||||||
InstrSize InstrSize({INSTRUCTION[31:24],INSTRUCTION[21:19]},Isize);
|
InstrSize InstrSize({INSTRUCTION[31:24],INSTRUCTION[21:19]},Isize);
|
||||||
/* verilator lint_off UNDRIVEN */
|
|
||||||
wire [2:0] fifoIsize;
|
wire [2:0] fifoIsize;
|
||||||
wire Isit1;
|
wire Isit1;
|
||||||
/* verilator lint_on UNDRIVEN */
|
|
||||||
`ifdef EARLY_VALID_INSTRUCTION
|
`ifdef EARLY_VALID_INSTRUCTION
|
||||||
InstrSize fifoInstrSize({INPUT_FIFO[FIFO_start][7:0],INPUT_FIFO[FIFO_start+1][5:3]},fifoIsize);
|
InstrSize fifoInstrSize({INPUT_FIFO[FIFO_start][7:0],INPUT_FIFO[FIFO_start+1][5:3]},fifoIsize);
|
||||||
Is1 Is1(INPUT_FIFO[FIFO_start][7:0],Isit1);
|
Is1 Is1(INPUT_FIFO[FIFO_start][7:0],Isit1);
|
||||||
@ -310,16 +301,16 @@ always @( proc_state ) begin
|
|||||||
was_dec<=0;
|
was_dec<=0;
|
||||||
/* verilator lint_off BLKSEQ */
|
/* verilator lint_off BLKSEQ */
|
||||||
FIFO_start = FIFO_start + {1'b0,Isize};
|
FIFO_start = FIFO_start + {1'b0,Isize};
|
||||||
INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};;
|
|
||||||
/* verilator lint_on BLKSEQ */
|
/* verilator lint_on BLKSEQ */
|
||||||
|
INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};;
|
||||||
VALID_INSTRUCTION <= 0;
|
VALID_INSTRUCTION <= 0;
|
||||||
end else if ( SIMPLE_MICRO==1 && was_simple == 1) begin
|
end else if ( SIMPLE_MICRO==1 && was_simple == 1) begin
|
||||||
was_simple<=0;
|
was_simple<=0;
|
||||||
was_dec<=0;
|
was_dec<=0;
|
||||||
/* verilator lint_off BLKSEQ */
|
/* verilator lint_off BLKSEQ */
|
||||||
FIFO_start = FIFO_start + {1'b0,Isize};
|
FIFO_start = FIFO_start + {1'b0,Isize};
|
||||||
INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};;
|
|
||||||
/* verilator lint_on BLKSEQ */
|
/* verilator lint_on BLKSEQ */
|
||||||
|
INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};;
|
||||||
VALID_INSTRUCTION <= 0;
|
VALID_INSTRUCTION <= 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -336,54 +327,3 @@ always @( posedge jump_req ) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
/* Pre-Decode the instruction size */
|
|
||||||
/* IN: {CIR[15:8],CIR[5:3]} */
|
|
||||||
/* OUT: number in bytes */
|
|
||||||
module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT );
|
|
||||||
always @( IN ) begin
|
|
||||||
casez(IN)
|
|
||||||
11'b0000_010?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* ADD - Add Immediate word/byte to accumulator */
|
|
||||||
11'b1000_00??_101 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* SUB - Subtract immediate word/byte from register/memory */
|
|
||||||
11'b1000_00??_000 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* ADD - Add Immediate word/byte to register/memory */
|
|
||||||
11'b1000_00??_111 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* CMP - compare Immediate with register / memory */
|
|
||||||
11'b1011_????_??? : VERDICT <= 3'd2+{2'b0,IN[6:6]}; /* MOV - Move Immediate byte to register */
|
|
||||||
11'b1000_10??_??? : VERDICT <= 3'd2; /* MOV - Reg/Mem to/from register */
|
|
||||||
11'b0100_????_??? : VERDICT <= 3'd1; /* DEC - Decrement Register | INC - Increment Register */
|
|
||||||
11'b1111_111?_00? : VERDICT <= 3'd2; /* INC - Register/Memory | DEC - Register/Memory */
|
|
||||||
11'b1111_0100_??? : VERDICT <= 3'd1; /* HLT - Halt */
|
|
||||||
11'b0011_110?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* CMP - Compare Immediate with accumulator */
|
|
||||||
11'b0111_????_??? : VERDICT <= 3'd2; /* Conditional relative jumps ( JE/JZ, JS/JNS ... ) */
|
|
||||||
11'b1110_1011_??? : VERDICT <= 3'd2; /* JMP - Unconditional jump direct within segment (short) */
|
|
||||||
11'b1110_1000_??? : VERDICT <= 3'd3; /* CALL - Direct call within segment */
|
|
||||||
11'b1100_0011_??? : VERDICT <= 3'd1; /* RET - Return from call within segment */
|
|
||||||
11'b1010_101?_??? : VERDICT <= 3'd1; /* STOS - Write byte/word to [DI] and increment accordingly */
|
|
||||||
11'b0101_0???_??? : VERDICT <= 3'd1; /* PUSH - SP-=2; [SP]=REG */
|
|
||||||
11'b1111_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */
|
|
||||||
11'b0101_1???_??? : VERDICT <= 3'd1; /* POP - REG=[SP]; SP+=2 */
|
|
||||||
11'b1111_1111_100 : VERDICT <= 3'd2; /* JMP - Unconditional indirect within segment jump */
|
|
||||||
11'b1100_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* MOV - Move immediate to register/memory */
|
|
||||||
11'b1100_1101_??? : VERDICT <= 3'd2; /* INT - execute interrupt handler */
|
|
||||||
11'b1110_011?_??? : VERDICT <= 3'd2; /* OUT - write AL or AX to a defined output port */
|
|
||||||
11'b1100_1111_??? : VERDICT <= 3'd1; /* IRET - Return from interrupt */
|
|
||||||
default:begin end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`ifdef EARLY_VALID_INSTRUCTION
|
|
||||||
module Is1 ( input [7:0] IN, output reg VERDICT );
|
|
||||||
always @( IN ) begin
|
|
||||||
casez(IN)
|
|
||||||
8'b0100_???? : VERDICT <= 1; /* DEC - Decrement Register | INC - Increment Register */
|
|
||||||
8'b1111_0100 : VERDICT <= 1; /* HLT - Halt */
|
|
||||||
8'b1100_0011 : VERDICT <= 1; /* RET - Return from call within segment */
|
|
||||||
8'b1010_101? : VERDICT <= 1; /* STOS - Write byte/word to [DI] and increment accordingly */
|
|
||||||
8'b0101_0??? : VERDICT <= 1; /* PUSH - SP-=2; [SP]=REG */
|
|
||||||
8'b0101_1??? : VERDICT <= 1; /* POP - REG=[SP]; SP+=2 */
|
|
||||||
8'b1100_1111 : VERDICT <= 1; /* IRET - Return from interrupt */
|
|
||||||
default:begin VERDICT<= 0; end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
endmodule
|
|
||||||
`endif
|
|
||||||
|
@ -29,9 +29,16 @@
|
|||||||
* for the maximum instruction size worth of bytes */
|
* for the maximum instruction size worth of bytes */
|
||||||
`define EARLY_VALID_INSTRUCTION
|
`define EARLY_VALID_INSTRUCTION
|
||||||
|
|
||||||
|
/* Size is in powers of two with minimal 3.
|
||||||
|
* 3 : 8 Bytes
|
||||||
|
* 4 : 16 Bytes
|
||||||
|
* 5 : 32 Bytes
|
||||||
|
* . : ... */
|
||||||
|
`define L1_CACHE_SIZE 4 // Don't change it! some parts of code still assume it to be 4
|
||||||
|
|
||||||
|
|
||||||
/* Internal */
|
|
||||||
|
/********** Internal **********/
|
||||||
`ifdef EARLY_VALID_INSTRUCTION
|
`ifdef EARLY_VALID_INSTRUCTION
|
||||||
`define EARLY_VALID_INSTRUCTION_ 1
|
`define EARLY_VALID_INSTRUCTION_ 1
|
||||||
`else
|
`else
|
||||||
|
164
system/decoder.v
164
system/decoder.v
@ -43,37 +43,64 @@ assign DATA=ucode_rom[ADDR];
|
|||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
// verilator lint_off UNUSEDSIGNAL
|
|
||||||
module decoder(
|
module decoder(
|
||||||
input wire [15:0] CIR,input wire [15:0] FLAGS, output wire [2:0] INSTRUCTION_INFO, output wire [`ERROR_BITS:0] DECODER_SIGNALS, output reg [`EXEC_STATE_BITS-1:0] next_state
|
/* INPUTS */ input wire [15:0] CIR,input wire [15:0] FLAGS
|
||||||
,output reg [2:0]IN_MOD, output reg [2:0]RM, output reg [15:0] PARAM1,output reg [15:0] PARAM2
|
/* MICROCODE */ ,output reg [`UCODE_ADDR_BITS-1:0] seq_addr_entry, input wire SIMPLE_MICRO, input wire [`UCODE_ADDR_BITS-1:0] seq_addr_input
|
||||||
,output reg [1:0]in_alu_sel1,output reg [1:0]in_alu_sel2,output reg [2:0]OUT_MOD
|
/* OUTPUT */ ,output wire [`EXEC_STATE_BITS+`ERROR_BITS+65:0] OUTPUT
|
||||||
,output wire [11:0]REGISTER_FILE_CONTROL
|
|
||||||
,output reg [2:0]ALU_1OP
|
|
||||||
,output reg [`UCODE_ADDR_BITS-1:0] seq_addr_entry, input wire SIMPLE_MICRO, input wire [`UCODE_ADDR_BITS-1:0] seq_addr_input
|
|
||||||
,output reg memio_address_select
|
|
||||||
,output reg MEM_OR_IO
|
|
||||||
);
|
);
|
||||||
// verilator lint_on UNUSEDSIGNAL
|
|
||||||
|
reg [2:0]IN_MOD;
|
||||||
|
assign OUTPUT[2:0] = IN_MOD;
|
||||||
|
|
||||||
|
reg [2:0]RM;
|
||||||
|
assign OUTPUT[5:3] = RM;
|
||||||
|
|
||||||
|
reg memio_address_select;
|
||||||
|
assign OUTPUT[6:6] = memio_address_select;
|
||||||
|
|
||||||
|
reg MEM_OR_IO;
|
||||||
|
assign OUTPUT[7:7] = MEM_OR_IO;
|
||||||
|
|
||||||
|
reg [15:0] PARAM1;
|
||||||
|
assign OUTPUT[23:8] = PARAM1;
|
||||||
|
|
||||||
|
reg [15:0] PARAM2;
|
||||||
|
assign OUTPUT[39:24] = PARAM2;
|
||||||
|
|
||||||
|
reg [2:0]ALU_OP;
|
||||||
|
assign OUTPUT[42:40] = ALU_OP;
|
||||||
|
|
||||||
|
reg [1:0]in_alu_sel1;
|
||||||
|
assign OUTPUT[44:43] = in_alu_sel1;
|
||||||
|
|
||||||
|
reg [1:0]in_alu_sel2;
|
||||||
|
assign OUTPUT[46:45] = in_alu_sel2;
|
||||||
|
|
||||||
|
reg [2:0]OUT_MOD;
|
||||||
|
assign OUTPUT[49:47] = OUT_MOD;
|
||||||
|
|
||||||
reg [3:0]reg_read_port1_addr;
|
reg [3:0]reg_read_port1_addr;
|
||||||
reg [3:0]reg_read_port2_addr;
|
assign OUTPUT[53:50] = reg_read_port1_addr;
|
||||||
reg [3:0]reg_write_addr;
|
|
||||||
assign REGISTER_FILE_CONTROL={reg_write_addr,reg_read_port1_addr,reg_read_port2_addr};
|
reg [3:0]reg_read_port2_addr;
|
||||||
|
assign OUTPUT[57:54] = reg_read_port2_addr;
|
||||||
|
|
||||||
|
reg [3:0]reg_write_addr;
|
||||||
|
assign OUTPUT[61:58] = reg_write_addr;
|
||||||
|
|
||||||
/* For correct fetching of instructions and global options for the alu */
|
|
||||||
reg Wbit,Sbit,opcode_size;
|
reg Wbit,Sbit,opcode_size;
|
||||||
assign INSTRUCTION_INFO={Wbit,Sbit,opcode_size};
|
assign OUTPUT[64:62] = {Wbit,Sbit,opcode_size};
|
||||||
|
|
||||||
reg [`ERROR_BITS-1:0] ERROR;
|
reg [`ERROR_BITS-1:0] ERROR;
|
||||||
reg HALT;
|
reg HALT;
|
||||||
assign DECODER_SIGNALS={ERROR,HALT};
|
assign OUTPUT[`ERROR_BITS+65:65]={ERROR,HALT};
|
||||||
|
|
||||||
|
reg [`EXEC_STATE_BITS-1:0] next_state;
|
||||||
|
assign OUTPUT[`EXEC_STATE_BITS+`ERROR_BITS+65:`ERROR_BITS+66] = next_state;
|
||||||
|
|
||||||
|
/* verilator lint_off UNUSEDSIGNAL */
|
||||||
// verilator lint_off UNUSEDSIGNAL
|
|
||||||
wire [`UCODE_DATA_BITS-1:0] ucode_data;
|
wire [`UCODE_DATA_BITS-1:0] ucode_data;
|
||||||
// verilator lint_on UNUSEDSIGNAL
|
/* verilator lint_on UNUSEDSIGNAL */
|
||||||
|
|
||||||
microcode ucode(seq_addr_input,ucode_data);
|
microcode ucode(seq_addr_input,ucode_data);
|
||||||
|
|
||||||
@ -97,7 +124,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
11'b0000_010?_??? : begin
|
11'b0000_010?_??? : begin
|
||||||
/* ADD - Add Immediate word/byte to accumulator */
|
/* ADD - Add Immediate word/byte to accumulator */
|
||||||
/* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/
|
/* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/
|
||||||
opcode_size=0; //TODO: move the decoding done in BIU here and use theat size checker
|
opcode_size=0;
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
IN_MOD=3'b011;
|
IN_MOD=3'b011;
|
||||||
in_alu_sel1=2'b00;
|
in_alu_sel1=2'b00;
|
||||||
@ -106,7 +133,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
reg_read_port2_addr={Wbit,3'b000};
|
reg_read_port2_addr={Wbit,3'b000};
|
||||||
reg_write_addr={Wbit,3'b000};
|
reg_write_addr={Wbit,3'b000};
|
||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_OP=`ALU_OP_ADD;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
if(Wbit)
|
if(Wbit)
|
||||||
next_state=`EXEC_DE_LOAD_16_PARAM;
|
next_state=`EXEC_DE_LOAD_16_PARAM;
|
||||||
@ -148,8 +175,8 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
case(CIR[5:3])
|
case(CIR[5:3])
|
||||||
3'b000: ALU_1OP=`ALU_OP_ADD;
|
3'b000: ALU_OP=`ALU_OP_ADD;
|
||||||
3'b101: ALU_1OP=`ALU_OP_SUB_REVERSE;
|
3'b101: ALU_OP=`ALU_OP_SUB_REVERSE;
|
||||||
default:begin
|
default:begin
|
||||||
/*Should be impossible*/
|
/*Should be impossible*/
|
||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
@ -171,7 +198,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu_sel1=2'b00;
|
in_alu_sel1=2'b00;
|
||||||
OUT_MOD=3'b100;
|
OUT_MOD=3'b100;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
ALU_1OP=`ALU_OP_SUB;
|
ALU_OP=`ALU_OP_SUB;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
if(IN_MOD==3'b011)begin
|
if(IN_MOD==3'b011)begin
|
||||||
/*compare register with param*/
|
/*compare register with param*/
|
||||||
@ -199,7 +226,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
reg_write_addr={1'b0,CIR[10:8]};
|
reg_write_addr={1'b0,CIR[10:8]};
|
||||||
PARAM1[7:0]=CIR[7:0];
|
PARAM1[7:0]=CIR[7:0];
|
||||||
PARAM2=0;
|
PARAM2=0;
|
||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_OP=`ALU_OP_ADD;
|
||||||
next_state=`EXEC_WRITE_ENTRY;
|
next_state=`EXEC_WRITE_ENTRY;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
@ -214,7 +241,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
OUT_MOD=3'b011;
|
OUT_MOD=3'b011;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
reg_write_addr={1'b1,CIR[10:8]};
|
reg_write_addr={1'b1,CIR[10:8]};
|
||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_OP=`ALU_OP_ADD;
|
||||||
PARAM2=0;
|
PARAM2=0;
|
||||||
next_state=`EXEC_DE_LOAD_16_PARAM;
|
next_state=`EXEC_DE_LOAD_16_PARAM;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
@ -260,7 +287,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
end
|
end
|
||||||
reg_read_port2_addr={Wbit,CIR[5:3]};
|
reg_read_port2_addr={Wbit,CIR[5:3]};
|
||||||
end
|
end
|
||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_OP=`ALU_OP_ADD;
|
||||||
|
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
@ -281,9 +308,9 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
reg_read_port1_addr={1'b1,CIR[10:8]};
|
reg_read_port1_addr={1'b1,CIR[10:8]};
|
||||||
reg_write_addr={1'b1,CIR[10:8]};
|
reg_write_addr={1'b1,CIR[10:8]};
|
||||||
if(CIR[11:11]==0)
|
if(CIR[11:11]==0)
|
||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_OP=`ALU_OP_ADD;
|
||||||
else
|
else
|
||||||
ALU_1OP=`ALU_OP_SUB;
|
ALU_OP=`ALU_OP_SUB;
|
||||||
next_state=`EXEC_WRITE_ENTRY;
|
next_state=`EXEC_WRITE_ENTRY;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
@ -307,7 +334,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
reg_read_port2_addr={1'b0,RM};
|
reg_read_port2_addr={1'b0,RM};
|
||||||
reg_write_addr={1'b0,RM};
|
reg_write_addr={1'b0,RM};
|
||||||
|
|
||||||
ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD;
|
ALU_OP=(CIR[3:3]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD;
|
||||||
if ( IN_MOD == 3'b011 )
|
if ( IN_MOD == 3'b011 )
|
||||||
next_state=`EXEC_WRITE_ENTRY;
|
next_state=`EXEC_WRITE_ENTRY;
|
||||||
else
|
else
|
||||||
@ -340,7 +367,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu_sel2=2'b01;
|
in_alu_sel2=2'b01;
|
||||||
reg_read_port2_addr={Wbit,3'b000};
|
reg_read_port2_addr={Wbit,3'b000};
|
||||||
OUT_MOD=3'b100;
|
OUT_MOD=3'b100;
|
||||||
ALU_1OP=`ALU_OP_SUB;
|
ALU_OP=`ALU_OP_SUB;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
if(Wbit==1)
|
if(Wbit==1)
|
||||||
next_state=`EXEC_DE_LOAD_16_PARAM;
|
next_state=`EXEC_DE_LOAD_16_PARAM;
|
||||||
@ -365,7 +392,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu_sel1=2'b10;
|
in_alu_sel1=2'b10;
|
||||||
in_alu_sel2=2'b00;
|
in_alu_sel2=2'b00;
|
||||||
PARAM2={{8{CIR[7:7]}},CIR[7:0]};
|
PARAM2={{8{CIR[7:7]}},CIR[7:0]};
|
||||||
ALU_1OP=`ALU_OP_ADD_SIGNED_B;
|
ALU_OP=`ALU_OP_ADD_SIGNED_B;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
OUT_MOD=3'b101;
|
OUT_MOD=3'b101;
|
||||||
case(CIR[11:9])
|
case(CIR[11:9])
|
||||||
@ -413,7 +440,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu_sel1=2'b10;
|
in_alu_sel1=2'b10;
|
||||||
in_alu_sel2=2'b00;
|
in_alu_sel2=2'b00;
|
||||||
PARAM2={{8{CIR[7:7]}},CIR[7:0]};
|
PARAM2={{8{CIR[7:7]}},CIR[7:0]};
|
||||||
ALU_1OP=`ALU_OP_ADD_SIGNED_B;
|
ALU_OP=`ALU_OP_ADD_SIGNED_B;
|
||||||
OUT_MOD=3'b101;
|
OUT_MOD=3'b101;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
next_state=`EXEC_WRITE_ENTRY;
|
next_state=`EXEC_WRITE_ENTRY;
|
||||||
@ -484,7 +511,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
next_state=`EXEC_DE_LOAD_8_PARAM;
|
next_state=`EXEC_DE_LOAD_8_PARAM;
|
||||||
end
|
end
|
||||||
in_alu_sel1=2'b00; /* PARAM1 */
|
in_alu_sel1=2'b00; /* PARAM1 */
|
||||||
ALU_1OP=`ALU_OP_AND;
|
ALU_OP=`ALU_OP_AND;
|
||||||
case(IN_MOD)
|
case(IN_MOD)
|
||||||
3'b011:begin
|
3'b011:begin
|
||||||
in_alu_sel2=2'b01;
|
in_alu_sel2=2'b01;
|
||||||
@ -527,7 +554,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu_sel2=2'b00;
|
in_alu_sel2=2'b00;
|
||||||
next_state=`EXEC_MEMIO_READ;
|
next_state=`EXEC_MEMIO_READ;
|
||||||
end
|
end
|
||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_OP=`ALU_OP_ADD;
|
||||||
OUT_MOD=3'b101;
|
OUT_MOD=3'b101;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
@ -623,14 +650,14 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/*1:1 map essentially but I want to keep the spec for these bits separate
|
/*1:1 map essentially but I want to keep the spec for these bits separate
|
||||||
* from the alu op select bits*/
|
* from the alu op select bits*/
|
||||||
case(ucode_data[22:20])
|
case(ucode_data[22:20])
|
||||||
3'b000: ALU_1OP=`ALU_OP_ADD;
|
3'b000: ALU_OP=`ALU_OP_ADD;
|
||||||
3'b001: ALU_1OP=`ALU_OP_SUB;
|
3'b001: ALU_OP=`ALU_OP_SUB;
|
||||||
3'b010: ALU_1OP=`ALU_OP_AND;
|
3'b010: ALU_OP=`ALU_OP_AND;
|
||||||
3'b011: ALU_1OP=`ALU_OP_OR;
|
3'b011: ALU_OP=`ALU_OP_OR;
|
||||||
3'b100: ALU_1OP=`ALU_OP_XOR;
|
3'b100: ALU_OP=`ALU_OP_XOR;
|
||||||
3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B;
|
3'b101: ALU_OP=`ALU_OP_ADD_SIGNED_B;
|
||||||
3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE;
|
3'b110: ALU_OP=`ALU_OP_SUB_REVERSE;
|
||||||
3'b111: ALU_1OP=`ALU_OP_SHIFT_LEFT;
|
3'b111: ALU_OP=`ALU_OP_SHIFT_LEFT;
|
||||||
default: begin end
|
default: begin end
|
||||||
endcase
|
endcase
|
||||||
if(ucode_data[34:34]==0) /* Set reg read port 1 address */
|
if(ucode_data[34:34]==0) /* Set reg read port 1 address */
|
||||||
@ -649,3 +676,54 @@ end
|
|||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
// verilator lint_on BLKSEQ
|
// verilator lint_on BLKSEQ
|
||||||
|
|
||||||
|
|
||||||
|
/* IN: {CIR[15:8],CIR[5:3]} */
|
||||||
|
/* OUT: number in bytes */
|
||||||
|
module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT );
|
||||||
|
always @( IN ) begin
|
||||||
|
casez(IN)
|
||||||
|
11'b0000_010?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* ADD - Add Immediate word/byte to accumulator */
|
||||||
|
11'b1000_00??_101 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* SUB - Subtract immediate word/byte from register/memory */
|
||||||
|
11'b1000_00??_000 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* ADD - Add Immediate word/byte to register/memory */
|
||||||
|
11'b1000_00??_111 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* CMP - compare Immediate with register / memory */
|
||||||
|
11'b1011_????_??? : VERDICT <= 3'd2+{2'b0,IN[6:6]}; /* MOV - Move Immediate byte to register */
|
||||||
|
11'b1000_10??_??? : VERDICT <= 3'd2; /* MOV - Reg/Mem to/from register */
|
||||||
|
11'b0100_????_??? : VERDICT <= 3'd1; /* DEC - Decrement Register | INC - Increment Register */
|
||||||
|
11'b1111_111?_00? : VERDICT <= 3'd2; /* INC - Register/Memory | DEC - Register/Memory */
|
||||||
|
11'b1111_0100_??? : VERDICT <= 3'd1; /* HLT - Halt */
|
||||||
|
11'b0011_110?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* CMP - Compare Immediate with accumulator */
|
||||||
|
11'b0111_????_??? : VERDICT <= 3'd2; /* Conditional relative jumps ( JE/JZ, JS/JNS ... ) */
|
||||||
|
11'b1110_1011_??? : VERDICT <= 3'd2; /* JMP - Unconditional jump direct within segment (short) */
|
||||||
|
11'b1110_1000_??? : VERDICT <= 3'd3; /* CALL - Direct call within segment */
|
||||||
|
11'b1100_0011_??? : VERDICT <= 3'd1; /* RET - Return from call within segment */
|
||||||
|
11'b1010_101?_??? : VERDICT <= 3'd1; /* STOS - Write byte/word to [DI] and increment accordingly */
|
||||||
|
11'b0101_0???_??? : VERDICT <= 3'd1; /* PUSH - SP-=2; [SP]=REG */
|
||||||
|
11'b1111_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */
|
||||||
|
11'b0101_1???_??? : VERDICT <= 3'd1; /* POP - REG=[SP]; SP+=2 */
|
||||||
|
11'b1111_1111_100 : VERDICT <= 3'd2; /* JMP - Unconditional indirect within segment jump */
|
||||||
|
11'b1100_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* MOV - Move immediate to register/memory */
|
||||||
|
11'b1100_1101_??? : VERDICT <= 3'd2; /* INT - execute interrupt handler */
|
||||||
|
11'b1110_011?_??? : VERDICT <= 3'd2; /* OUT - write AL or AX to a defined output port */
|
||||||
|
11'b1100_1111_??? : VERDICT <= 3'd1; /* IRET - Return from interrupt */
|
||||||
|
default:begin end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`ifdef EARLY_VALID_INSTRUCTION
|
||||||
|
module Is1 ( input [7:0] IN, output reg VERDICT );
|
||||||
|
always @( IN ) begin
|
||||||
|
casez(IN)
|
||||||
|
8'b0100_???? : VERDICT <= 1; /* DEC - Decrement Register | INC - Increment Register */
|
||||||
|
8'b1111_0100 : VERDICT <= 1; /* HLT - Halt */
|
||||||
|
8'b1100_0011 : VERDICT <= 1; /* RET - Return from call within segment */
|
||||||
|
8'b1010_101? : VERDICT <= 1; /* STOS - Write byte/word to [DI] and increment accordingly */
|
||||||
|
8'b0101_0??? : VERDICT <= 1; /* PUSH - SP-=2; [SP]=REG */
|
||||||
|
8'b0101_1??? : VERDICT <= 1; /* POP - REG=[SP]; SP+=2 */
|
||||||
|
8'b1100_1111 : VERDICT <= 1; /* IRET - Return from interrupt */
|
||||||
|
default:begin VERDICT<= 0; end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
|
/* execute.v - Implements the instruction execution logic
|
||||||
|
|
||||||
|
This file is part of the 9086 project.
|
||||||
|
|
||||||
|
Copyright (c) 2023 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 <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
module execute_unit (
|
module execute_unit (
|
||||||
/* GENERAL */ input clock, input reset ,input Wbit, input Sbit, input opcode_size,input [23:0] INSTRUCTION_BUFFER,input valid_input
|
/* GENERAL */ input clock, input reset ,input Wbit, input Sbit, input opcode_size,input [23:0] INSTRUCTION_BUFFER,input valid_input
|
||||||
/* */ ,input [2:0] IN_MOD, input [2:0] OUT_MOD, input memio_address_select, input [15:0] ProgCount, input [2:0] RM, output reg [`ERROR_BITS-1:0] ERROR , input write /*TODO: REMOVE!!*/
|
/* */ ,input [2:0] IN_MOD, input [2:0] OUT_MOD, input memio_address_select, input [15:0] ProgCount, input [2:0] RM, output reg [`ERROR_BITS-1:0] ERROR , input write /*TODO: REMOVE!!*/
|
||||||
@ -13,12 +32,11 @@ module execute_unit (
|
|||||||
assign _exec_state_ = exec_state;
|
assign _exec_state_ = exec_state;
|
||||||
assign _ALU_O_ = ALU_O;
|
assign _ALU_O_ = ALU_O;
|
||||||
|
|
||||||
/*############ ALU / Execution units ########################################################## */
|
|
||||||
// ALU 1
|
|
||||||
reg [`EXEC_STATE_BITS-1:0] exec_state;
|
reg [`EXEC_STATE_BITS-1:0] exec_state;
|
||||||
|
|
||||||
reg [15:0] PARAM1,PARAM2;
|
reg [15:0] PARAM1,PARAM2;
|
||||||
|
|
||||||
|
/*############ ALU / Execution units ################################################## */
|
||||||
|
|
||||||
mux4 #(.WIDTH(16)) MUX16_1A(
|
mux4 #(.WIDTH(16)) MUX16_1A(
|
||||||
/*0*/ PARAM1,
|
/*0*/ PARAM1,
|
||||||
/*1*/ reg_read_port1_data,
|
/*1*/ reg_read_port1_data,
|
||||||
@ -41,28 +59,24 @@ wire [15:0] ALU_O;
|
|||||||
wire [7:0] ALU_FLAGS;
|
wire [7:0] ALU_FLAGS;
|
||||||
|
|
||||||
ALU ALU1(
|
ALU ALU1(
|
||||||
.A(ALU_A),
|
/* INPUT 1 */ .A(ALU_A),
|
||||||
.B(ALU_B),
|
/* INPUT 2 */ .B(ALU_B),
|
||||||
.OUT(ALU_O),
|
/* OUTPUT */ .OUT(ALU_O),
|
||||||
.op(ALU_OP),
|
/* OPERATION */ .op(ALU_OP),
|
||||||
.FLAGS(ALU_FLAGS),
|
/* FLAGS */ .FLAGS(ALU_FLAGS),
|
||||||
.Wbit(Wbit)
|
/* Wbit */ .Wbit(Wbit)
|
||||||
);
|
);
|
||||||
|
|
||||||
//reg valid_input_;
|
/*############ Execute logic ########################################################## */
|
||||||
|
|
||||||
always @(posedge valid_input) begin
|
always @(posedge valid_input) begin
|
||||||
exec_state <= init_state;
|
exec_state <= init_state;
|
||||||
//valid_input_ <= 1;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(negedge set_initial_values) begin
|
always @(negedge set_initial_values) begin
|
||||||
PARAM1 <= PARAM1_INIT;
|
PARAM1 <= PARAM1_INIT;
|
||||||
PARAM2 <= PARAM2_INIT;
|
PARAM2 <= PARAM2_INIT;
|
||||||
end
|
end
|
||||||
//always @(negedge valid_input) begin
|
|
||||||
// valid_input_ <= 0;
|
|
||||||
//end
|
|
||||||
|
|
||||||
always @(negedge reset) begin
|
always @(negedge reset) begin
|
||||||
exec_state <= `EXEC_HALT;
|
exec_state <= `EXEC_HALT;
|
||||||
@ -76,7 +90,6 @@ end
|
|||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
case (exec_state)
|
case (exec_state)
|
||||||
`EXEC_RESET: begin
|
`EXEC_RESET: begin
|
||||||
//valid_input_ <= 0;
|
|
||||||
biu_write_request <= 0;
|
biu_write_request <= 0;
|
||||||
biu_read_request <= 0;
|
biu_read_request <= 0;
|
||||||
biu_data_direction <= 0;
|
biu_data_direction <= 0;
|
||||||
@ -87,7 +100,6 @@ always @(posedge clock) begin
|
|||||||
end
|
end
|
||||||
`EXEC_DONE:begin
|
`EXEC_DONE:begin
|
||||||
reg_write_we <= 1;
|
reg_write_we <= 1;
|
||||||
//valid_input_ <= 0;
|
|
||||||
biu_jump_req <= 0;
|
biu_jump_req <= 0;
|
||||||
use_exec_reg_addr <= 0;
|
use_exec_reg_addr <= 0;
|
||||||
end
|
end
|
||||||
|
@ -23,54 +23,61 @@
|
|||||||
`include "ucode_header.v"
|
`include "ucode_header.v"
|
||||||
`include "error_header.v"
|
`include "error_header.v"
|
||||||
|
|
||||||
//HALT: active high
|
|
||||||
//IOMEM: 1=IO 0=MEM
|
|
||||||
//write: active low
|
|
||||||
//read: active low
|
|
||||||
//reset: active low
|
|
||||||
|
|
||||||
`define PROC_STATE_BITS 3
|
`define PROC_STATE_BITS 3
|
||||||
`define PROC_RESET 3'b000
|
`define PROC_RESET 3'b000
|
||||||
`define PROC_DE_STATE_ENTRY 3'b001
|
`define PROC_DE_STATE_ENTRY 3'b001
|
||||||
`define PROC_WAIT 3'b010
|
`define PROC_WAIT 3'b010
|
||||||
`define PROC_HALT 3'b011
|
`define PROC_HALT 3'b011
|
||||||
|
|
||||||
module processor ( input clock, input reset, output [19:0] external_address_bus, inout [15:0] external_data_bus,output read, output write,output BHE,output IOMEM, output reg HALT,output [`ERROR_BITS-1:0] ERROR);
|
//HALT: active high
|
||||||
|
//IOMEM: 1=IO 0=MEM
|
||||||
|
//BHE: active low
|
||||||
|
//write: active low
|
||||||
|
//read: active low
|
||||||
|
//reset: active low
|
||||||
|
|
||||||
|
module processor ( input clock, input reset, output [19:0] external_address_bus, inout [15:0] external_data_bus,output read, output write,output BHE,output IOMEM, output wire HALT,output [`ERROR_BITS-1:0] ERROR);
|
||||||
|
|
||||||
/* If there is an error either from the decoder or execution unit set it to ERROR */
|
/* If there is an error either from the decoder or execution unit set it to ERROR */
|
||||||
assign ERROR=(DE_ERROR_sampled!=`ERR_NO_ERROR)?DE_ERROR_sampled:(EXEC_ERROR!=`ERR_NO_ERROR)?EXEC_ERROR:`ERR_NO_ERROR;
|
assign ERROR=(DE_ERROR!=`ERR_NO_ERROR)?DE_ERROR:(EXEC_ERROR!=`ERR_NO_ERROR)?EXEC_ERROR:`ERR_NO_ERROR;
|
||||||
|
|
||||||
/*** Global Definitions ***/
|
|
||||||
reg [`PROC_STATE_BITS-1:0] state;
|
reg [`PROC_STATE_BITS-1:0] state;
|
||||||
|
|
||||||
/*############ Execution Unit ################################################## */
|
/*############ Execution Unit ################################################### */
|
||||||
reg [1:0] in_alu_sel1;
|
|
||||||
reg [1:0] in_alu_sel2;
|
wire [1:0] in_alu_sel1, in_alu_sel2;
|
||||||
|
assign in_alu_sel1 = DE_OUTPUT_sampled[44:43];
|
||||||
|
assign in_alu_sel2 = DE_OUTPUT_sampled[46:45];
|
||||||
|
|
||||||
wire [`EXEC_STATE_BITS-1:0] exec_state;
|
wire [`EXEC_STATE_BITS-1:0] exec_state;
|
||||||
|
|
||||||
reg valid_exec_data;
|
reg valid_exec_data, set_initial_values;
|
||||||
|
|
||||||
wire [`ERROR_BITS-1:0] EXEC_ERROR;
|
wire [`ERROR_BITS-1:0] EXEC_ERROR;
|
||||||
|
|
||||||
wire use_exec_reg_addr;
|
wire use_exec_reg_addr;
|
||||||
|
|
||||||
wire [3:0] EXEC_reg_read_port1_addr;
|
wire [3:0] EXEC_reg_read_port1_addr;
|
||||||
reg [2:0] IN_MOD,OUT_MOD;
|
|
||||||
reg [`EXEC_STATE_BITS-1:0] exec_state_init;
|
|
||||||
reg [`ALU_OP_BITS-1:0] ALU_OP;
|
|
||||||
wire [15:0] ALU_O;
|
wire [15:0] ALU_O;
|
||||||
wire [7:0]EXEC_FLAGS;
|
wire [7:0]EXEC_FLAGS;
|
||||||
reg [15:0] PARAM1_INIT;
|
|
||||||
reg [15:0] PARAM2_INIT;
|
wire [15:0] PARAM1_INIT, PARAM2_INIT;
|
||||||
reg set_initial_values;
|
assign PARAM1_INIT = DE_OUTPUT_sampled[23:8];
|
||||||
|
assign PARAM2_INIT = DE_OUTPUT_sampled[39:24];
|
||||||
|
|
||||||
|
wire [2:0] IN_MOD,OUT_MOD;
|
||||||
|
assign IN_MOD=DE_OUTPUT_sampled[2:0];
|
||||||
|
assign OUT_MOD=DE_OUTPUT_sampled[49:47];
|
||||||
|
|
||||||
|
wire [`ALU_OP_BITS-1:0] ALU_OP;
|
||||||
|
assign ALU_OP = DE_OUTPUT_sampled[42:40];
|
||||||
|
|
||||||
execute_unit execute_unit (
|
execute_unit execute_unit (
|
||||||
/* GENERAL */ clock, reset, Wbit, Sbit, opcode_size, INSTRUCTION_BUFFER,valid_exec_data
|
/* GENERAL */ clock, reset, Wbit, Sbit, opcode_size, INSTRUCTION_BUFFER,valid_exec_data
|
||||||
/* */ ,IN_MOD, OUT_MOD,memio_address_select, ProgCount, RM, EXEC_ERROR, write
|
/* */ ,IN_MOD, OUT_MOD,memio_address_select, ProgCount, RM, EXEC_ERROR, write
|
||||||
/* */ ,set_initial_values
|
/* */ ,set_initial_values
|
||||||
/* PARAM */ ,PARAM1_INIT,PARAM2_INIT
|
/* PARAM */ ,PARAM1_INIT,PARAM2_INIT
|
||||||
/* STATE CONTROL */ ,exec_state, exec_state_init
|
/* STATE CONTROL */ ,exec_state, next_state
|
||||||
/* ALU CONTROL */ ,in_alu_sel1, in_alu_sel2, ALU_OP, ALU_O
|
/* ALU CONTROL */ ,in_alu_sel1, in_alu_sel2, ALU_OP, ALU_O
|
||||||
/* REGISTER DATA */ ,reg_read_port1_data, reg_read_port2_data, EXEC_reg_read_port1_addr, use_exec_reg_addr, reg_write_we
|
/* REGISTER DATA */ ,reg_read_port1_data, reg_read_port2_data, EXEC_reg_read_port1_addr, use_exec_reg_addr, reg_write_we
|
||||||
/* FLAFS */ ,EXEC_FLAGS
|
/* FLAFS */ ,EXEC_FLAGS
|
||||||
@ -79,138 +86,96 @@ execute_unit execute_unit (
|
|||||||
|
|
||||||
/*############ Bus Interface Unit ############################################### */
|
/*############ Bus Interface Unit ############################################### */
|
||||||
|
|
||||||
wire [31:0] INSTRUCTION;
|
wire [15:0] INSTRUCTION_LOCATION, BIU_ADDRESS_INPUT;
|
||||||
wire biu_jump_req;
|
|
||||||
wire VALID_INSTRUCTION;
|
|
||||||
wire [15:0] INSTRUCTION_LOCATION;
|
|
||||||
wire [15:0] BIU_ADDRESS_INPUT;
|
|
||||||
wire [15:0] BIU_DATA;
|
wire [15:0] BIU_DATA;
|
||||||
wire biu_write_request;
|
wire [31:0] INSTRUCTION;
|
||||||
wire biu_data_direction;
|
wire biu_write_request, biu_read_request, BIU_VALID_DATA;
|
||||||
wire biu_read_request;
|
wire biu_jump_req, biu_data_direction,VALID_INSTRUCTION;
|
||||||
wire BIU_VALID_DATA;
|
|
||||||
|
|
||||||
BIU BIU(
|
BIU BIU(
|
||||||
clock,reset,external_address_bus,external_data_bus,read,write,BHE,IOMEM,
|
/* Outside world */ clock,reset,external_address_bus
|
||||||
INSTRUCTION,VALID_INSTRUCTION,INSTRUCTION_LOCATION,biu_jump_req,BIU_ADDRESS_INPUT,BIU_DATA,biu_write_request,biu_read_request,Wbit,BIU_VALID_DATA,MEM_OR_IO,
|
/* */ ,external_data_bus,read,write,BHE,IOMEM
|
||||||
state,SIMPLE_MICRO
|
/* Internal */ ,INSTRUCTION,VALID_INSTRUCTION,INSTRUCTION_LOCATION,biu_jump_req
|
||||||
|
/* */ ,BIU_ADDRESS_INPUT,BIU_DATA,biu_write_request,biu_read_request,Wbit,BIU_VALID_DATA,MEM_OR_IO
|
||||||
|
/* */ ,state,SIMPLE_MICRO
|
||||||
);
|
);
|
||||||
assign BIU_DATA= biu_data_direction ? 16'hz : (memio_address_select ? reg_read_port1_data : ALU_O);
|
assign BIU_DATA= biu_data_direction ? 16'hz : (memio_address_select ? reg_read_port1_data : ALU_O);
|
||||||
|
|
||||||
/*############ Decoder ########################################################## */
|
/*############ Decoder ########################################################## */
|
||||||
reg Wbit, Sbit, opcode_size;
|
|
||||||
wire DE_Wbit, DE_Sbit, DE_opcode_size;
|
|
||||||
wire [`EXEC_STATE_BITS-1:0] next_state;
|
|
||||||
reg [2:0]RM;
|
|
||||||
wire [15:0]DE_PARAM1;// Input param1 form decoder to alu
|
|
||||||
wire [15:0]DE_PARAM2;
|
|
||||||
wire [2:0]DE_IN_MOD;
|
|
||||||
wire [2:0]DE_RM;
|
|
||||||
wire [2:0]DE_OUT_MOD;
|
|
||||||
wire [`ERROR_BITS-1:0] DE_ERROR;
|
|
||||||
wire DE_HALT;
|
|
||||||
wire [3:0]DE_reg_read_port1_addr,DE_reg_write_addr,DE_reg_read_port2_addr;
|
|
||||||
wire [11:0]DE_REGISTER_CONTROL;
|
|
||||||
wire [2:0]INSTRUCTION_INFO;
|
|
||||||
wire [`ERROR_BITS:0]DECODER_SIGNALS;
|
|
||||||
wire [`UCODE_ADDR_BITS-1:0] ucode_seq_addr_entry;
|
wire [`UCODE_ADDR_BITS-1:0] ucode_seq_addr_entry;
|
||||||
|
|
||||||
reg SIMPLE_MICRO; /* output simple decodings (=0) or microcode data (=1) */
|
|
||||||
//TODO : remove completely?
|
|
||||||
reg memio_address_select;
|
|
||||||
wire DE_memio_address_select;
|
|
||||||
wire DE_MEM_OR_IO;
|
|
||||||
reg MEM_OR_IO;
|
|
||||||
wire [1:0] DE_in_alu_sel1;
|
|
||||||
wire [1:0] DE_in_alu_sel2;
|
|
||||||
reg [`ALU_OP_BITS-1:0] DE_ALU_OP;
|
|
||||||
decoder decoder(
|
|
||||||
.CIR(INSTRUCTION[31:16]),
|
|
||||||
.FLAGS(FLAGS),
|
|
||||||
.INSTRUCTION_INFO(INSTRUCTION_INFO),
|
|
||||||
.DECODER_SIGNALS(DECODER_SIGNALS),
|
|
||||||
.next_state(next_state),
|
|
||||||
.IN_MOD(DE_IN_MOD),
|
|
||||||
.RM(DE_RM),
|
|
||||||
.PARAM1(DE_PARAM1),
|
|
||||||
.PARAM2(DE_PARAM2),
|
|
||||||
.in_alu_sel1(DE_in_alu_sel1),
|
|
||||||
.in_alu_sel2(DE_in_alu_sel2),
|
|
||||||
.OUT_MOD(DE_OUT_MOD),
|
|
||||||
.REGISTER_FILE_CONTROL(DE_REGISTER_CONTROL),
|
|
||||||
.ALU_1OP(DE_ALU_OP),
|
|
||||||
.seq_addr_entry(ucode_seq_addr_entry),
|
|
||||||
.SIMPLE_MICRO(SIMPLE_MICRO),
|
|
||||||
.seq_addr_input(ucode_seq_addr),
|
|
||||||
.memio_address_select(DE_memio_address_select),
|
|
||||||
.MEM_OR_IO(DE_MEM_OR_IO)
|
|
||||||
);
|
|
||||||
|
|
||||||
assign DE_Wbit=INSTRUCTION_INFO[2:2];
|
|
||||||
assign DE_Sbit=INSTRUCTION_INFO[1:1];
|
|
||||||
assign DE_opcode_size=INSTRUCTION_INFO[0:0];
|
|
||||||
|
|
||||||
assign DE_reg_write_addr=DE_REGISTER_CONTROL[11:8];
|
|
||||||
assign DE_reg_read_port1_addr=DE_REGISTER_CONTROL[7:4];
|
|
||||||
assign DE_reg_read_port2_addr=DE_REGISTER_CONTROL[3:0];
|
|
||||||
|
|
||||||
assign DE_HALT=DECODER_SIGNALS[0:0];
|
|
||||||
assign DE_ERROR=DECODER_SIGNALS[`ERROR_BITS:1];
|
|
||||||
reg [`ERROR_BITS-1:0] DE_ERROR_sampled;
|
|
||||||
|
|
||||||
reg [`UCODE_ADDR_BITS-1:0] ucode_seq_addr;
|
reg [`UCODE_ADDR_BITS-1:0] ucode_seq_addr;
|
||||||
|
reg SIMPLE_MICRO; /* output simple decodings (=0) or microcode data (=1) */
|
||||||
|
|
||||||
/*############ REGISTERS ########################################################## */
|
wire [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT;
|
||||||
|
reg [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT_sampled;
|
||||||
|
|
||||||
|
decoder decoder(
|
||||||
// verilator lint_off UNDRIVEN
|
/* INPUTS */ INSTRUCTION[31:16],FLAGS,
|
||||||
reg [15:0] FLAGS;
|
/* MICROCODE */ ucode_seq_addr_entry,SIMPLE_MICRO,ucode_seq_addr,
|
||||||
// verilator lint_on UNDRIVEN
|
/* OUTPUT */ DE_OUTPUT
|
||||||
|
|
||||||
//Architectural Register file
|
|
||||||
reg [3:0] reg_write_addr;
|
|
||||||
wire [15:0] reg_write_data;
|
|
||||||
wire reg_write_we;
|
|
||||||
wire [3:0] reg_read_port1_addr;
|
|
||||||
reg [15:0] reg_read_port1_data;
|
|
||||||
reg [3:0] reg_read_port2_addr;
|
|
||||||
reg [15:0] reg_read_port2_data;
|
|
||||||
reg [1:0] reg_write_in_sel;
|
|
||||||
|
|
||||||
mux4 #(.WIDTH(16)) REG_FILE_WRITE_IN_MUX(
|
|
||||||
ALU_O,
|
|
||||||
16'hz,
|
|
||||||
16'hz,
|
|
||||||
16'hz,
|
|
||||||
reg_write_in_sel,
|
|
||||||
reg_write_data);
|
|
||||||
|
|
||||||
register_file register_file(
|
|
||||||
.write_port1_addr(reg_write_addr),
|
|
||||||
.write_port1_data(reg_write_data),
|
|
||||||
.write_port1_we(reg_write_we),
|
|
||||||
.read_port1_addr(reg_read_port1_addr),
|
|
||||||
.read_port1_data(reg_read_port1_data),
|
|
||||||
.read_port2_addr(reg_read_port2_addr),
|
|
||||||
.read_port2_data(reg_read_port2_data)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assign reg_read_port1_addr = use_exec_reg_addr ? EXEC_reg_read_port1_addr : reg_read_port1_addr_latched;
|
wire [2:0] RM;
|
||||||
|
assign RM = DE_OUTPUT_sampled[5:3];
|
||||||
|
|
||||||
|
wire memio_address_select;
|
||||||
|
assign memio_address_select=DE_OUTPUT_sampled[6:6];
|
||||||
|
|
||||||
|
wire [3:0] DE_reg_read_port1_addr,DE_reg_read_port2_addr;
|
||||||
|
assign DE_reg_read_port1_addr=DE_OUTPUT_sampled[53:50];
|
||||||
|
assign DE_reg_read_port2_addr=DE_OUTPUT_sampled[57:54];
|
||||||
|
|
||||||
|
wire [3:0] reg_write_addr;
|
||||||
|
assign reg_write_addr=DE_OUTPUT_sampled[61:58];
|
||||||
|
|
||||||
|
wire MEM_OR_IO;
|
||||||
|
assign MEM_OR_IO = DE_OUTPUT_sampled[7:7];
|
||||||
|
|
||||||
|
wire Wbit, Sbit, opcode_size;
|
||||||
|
assign opcode_size=DE_OUTPUT_sampled[62:62];
|
||||||
|
assign Sbit=DE_OUTPUT_sampled[63:63];
|
||||||
|
assign Wbit=DE_OUTPUT_sampled[64:64];
|
||||||
|
|
||||||
|
wire [`ERROR_BITS-1:0] DE_ERROR;
|
||||||
|
assign HALT = DE_OUTPUT_sampled[65:65];
|
||||||
|
assign DE_ERROR = DE_OUTPUT_sampled[`ERROR_BITS+65:66];
|
||||||
|
|
||||||
|
wire [`EXEC_STATE_BITS-1:0] next_state;
|
||||||
|
assign next_state=DE_OUTPUT_sampled[`EXEC_STATE_BITS+`ERROR_BITS+65:`ERROR_BITS+66];
|
||||||
|
|
||||||
|
/*############ Registers ######################################################## */
|
||||||
|
|
||||||
|
reg [15:0] FLAGS;
|
||||||
reg [15:0] ProgCount;
|
reg [15:0] ProgCount;
|
||||||
|
|
||||||
/*############ Processor state machine ########################################################## */
|
wire [3:0] reg_read_port1_addr;
|
||||||
reg [3:0] reg_read_port1_addr_latched;
|
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;
|
||||||
|
|
||||||
|
wire reg_write_we;
|
||||||
|
|
||||||
|
register_file register_file(
|
||||||
|
/* WRITE */ .write_port1_addr(reg_write_addr),
|
||||||
|
/* */ .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)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*############ Processor State Machine ########################################## */
|
||||||
|
|
||||||
/*** RESET LOGIC ***/
|
/*** RESET LOGIC ***/
|
||||||
/* verilator lint_off MULTIDRIVEN */
|
|
||||||
always @(negedge reset) begin
|
always @(negedge reset) begin
|
||||||
state <= `PROC_HALT; //TODO: race condition ??
|
state <= `PROC_HALT; //TODO: race condition ??
|
||||||
end
|
end
|
||||||
always @(posedge reset) begin
|
always @(posedge reset) begin
|
||||||
state <= `PROC_RESET;
|
state <= `PROC_RESET;
|
||||||
end
|
end
|
||||||
/* verilator lint_on MULTIDRIVEN */
|
|
||||||
|
|
||||||
/*** Processor stages ***/
|
/*** Processor stages ***/
|
||||||
|
|
||||||
@ -219,49 +184,28 @@ InstrSize InstrSize({INSTRUCTION[31:24],INSTRUCTION[21:19]},instr_end);
|
|||||||
|
|
||||||
reg [23:0] INSTRUCTION_BUFFER;
|
reg [23:0] INSTRUCTION_BUFFER;
|
||||||
|
|
||||||
|
|
||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
case(state)
|
case(state)
|
||||||
`PROC_RESET:begin
|
`PROC_RESET:begin
|
||||||
ucode_seq_addr <= `UCODE_NO_INSTRUCTION;
|
ucode_seq_addr <= `UCODE_NO_INSTRUCTION;
|
||||||
HALT <= 0;
|
DE_OUTPUT_sampled <= 0;
|
||||||
SIMPLE_MICRO <= 0;
|
SIMPLE_MICRO <= 0;
|
||||||
state <= `PROC_DE_STATE_ENTRY;
|
state <= `PROC_DE_STATE_ENTRY;
|
||||||
reg_write_in_sel <= 2'b00; //only got wirtten in IF
|
|
||||||
end
|
end
|
||||||
`PROC_DE_STATE_ENTRY:begin
|
`PROC_DE_STATE_ENTRY:begin
|
||||||
if(VALID_INSTRUCTION==1) begin
|
if(VALID_INSTRUCTION==1) begin
|
||||||
|
|
||||||
|
DE_OUTPUT_sampled <= DE_OUTPUT;
|
||||||
|
|
||||||
if(SIMPLE_MICRO==0)begin
|
if(SIMPLE_MICRO==0)begin
|
||||||
/* We cannot set these directly within
|
set_initial_values<=0;
|
||||||
* microcode so don't overwrite useful values
|
|
||||||
* each tie the next microcode is executed.
|
|
||||||
* Note this still allows to set initial values
|
|
||||||
* at the start of the microcode */
|
|
||||||
PARAM1_INIT <= DE_PARAM1;
|
|
||||||
PARAM2_INIT <= DE_PARAM2;
|
|
||||||
`ifdef DEBUG_PC_ADDRESS
|
`ifdef DEBUG_PC_ADDRESS
|
||||||
$display("Running command at %04x (%08x)",INSTRUCTION_LOCATION,INSTRUCTION);
|
$display("Running command at %04x (%08x)",INSTRUCTION_LOCATION,INSTRUCTION);
|
||||||
`endif
|
`endif
|
||||||
ProgCount <= INSTRUCTION_LOCATION+{12'b0,instr_end};
|
ProgCount <= INSTRUCTION_LOCATION+{12'b0,instr_end};
|
||||||
INSTRUCTION_BUFFER<=INSTRUCTION[23:0];
|
INSTRUCTION_BUFFER<=INSTRUCTION[23:0];
|
||||||
set_initial_values<=0;
|
|
||||||
end
|
end
|
||||||
DE_ERROR_sampled <= DE_ERROR;
|
|
||||||
IN_MOD <= DE_IN_MOD;
|
|
||||||
OUT_MOD <= DE_OUT_MOD;
|
|
||||||
RM <= DE_RM;
|
|
||||||
HALT <= DE_HALT;
|
|
||||||
Wbit <= DE_Wbit;
|
|
||||||
Sbit <= DE_Sbit;
|
|
||||||
opcode_size <= DE_opcode_size;
|
|
||||||
memio_address_select<=DE_memio_address_select;
|
|
||||||
reg_read_port1_addr_latched <= DE_reg_read_port1_addr;
|
|
||||||
reg_read_port2_addr <= DE_reg_read_port2_addr;
|
|
||||||
reg_write_addr <= DE_reg_write_addr;
|
|
||||||
MEM_OR_IO <= DE_MEM_OR_IO;
|
|
||||||
in_alu_sel1 <= DE_in_alu_sel1;
|
|
||||||
in_alu_sel2 <= DE_in_alu_sel2;
|
|
||||||
ALU_OP <= DE_ALU_OP;
|
|
||||||
if ( (ucode_seq_addr==`UCODE_NO_INSTRUCTION) && (ucode_seq_addr_entry!=`UCODE_NO_INSTRUCTION) )begin
|
if ( (ucode_seq_addr==`UCODE_NO_INSTRUCTION) && (ucode_seq_addr_entry!=`UCODE_NO_INSTRUCTION) )begin
|
||||||
/*switch to microcode decoding*/
|
/*switch to microcode decoding*/
|
||||||
ucode_seq_addr <= ucode_seq_addr_entry;
|
ucode_seq_addr <= ucode_seq_addr_entry;
|
||||||
@ -269,7 +213,6 @@ always @(posedge clock) begin
|
|||||||
/*keep state the same and rerun decode this time with all the data from the microcode rom*/
|
/*keep state the same and rerun decode this time with all the data from the microcode rom*/
|
||||||
end else begin
|
end else begin
|
||||||
valid_exec_data <= 1;
|
valid_exec_data <= 1;
|
||||||
exec_state_init <= next_state;
|
|
||||||
state <= `PROC_WAIT;
|
state <= `PROC_WAIT;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -277,7 +220,7 @@ always @(posedge clock) begin
|
|||||||
`PROC_WAIT:begin
|
`PROC_WAIT:begin
|
||||||
set_initial_values<=1;
|
set_initial_values<=1;
|
||||||
if( exec_state == `EXEC_DONE ) begin
|
if( exec_state == `EXEC_DONE ) begin
|
||||||
FLAGS[7:0] <= EXEC_FLAGS; //don't set all of them all the time!
|
FLAGS <= {8'b0,EXEC_FLAGS}; //TODO: don't set all of them all the time!
|
||||||
valid_exec_data<=0;
|
valid_exec_data<=0;
|
||||||
state <= `PROC_DE_STATE_ENTRY;
|
state <= `PROC_DE_STATE_ENTRY;
|
||||||
if( SIMPLE_MICRO == 1 ) begin
|
if( SIMPLE_MICRO == 1 ) begin
|
||||||
@ -296,5 +239,4 @@ always @(posedge clock) begin
|
|||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user