Added support for writing to memory
This commit is contained in:
parent
7c1067088c
commit
037f6dd7da
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ cpu/boot_code.txt
|
|||||||
cpu/brainfuck.bin
|
cpu/brainfuck.bin
|
||||||
cpu/brainfuck.txt
|
cpu/brainfuck.txt
|
||||||
cpu/memdump.txt
|
cpu/memdump.txt
|
||||||
|
cpu/memdump.bin
|
||||||
|
@ -22,6 +22,7 @@ VVP=processor.vvp
|
|||||||
.PHONY: brainf
|
.PHONY: brainf
|
||||||
brainf: ${VVP} brainfuck.txt
|
brainf: ${VVP} brainfuck.txt
|
||||||
vvp ${VVP} +BOOT_CODE=brainfuck.txt
|
vvp ${VVP} +BOOT_CODE=brainfuck.txt
|
||||||
|
grep -v '^//' memdump.txt | xxd -ps -c 2 -r > memdump.bin
|
||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: ${VVP} boot_code.txt
|
run: ${VVP} boot_code.txt
|
||||||
@ -34,6 +35,7 @@ build: ${VVP}
|
|||||||
wave: ${VVP} brainfuck.txt
|
wave: ${VVP} brainfuck.txt
|
||||||
vvp ${VVP} -lxt2 +BOOT_CODE=brainfuck.txt
|
vvp ${VVP} -lxt2 +BOOT_CODE=brainfuck.txt
|
||||||
gtkwave test.lx2 gtkwave_savefile.gtkw
|
gtkwave test.lx2 gtkwave_savefile.gtkw
|
||||||
|
grep -v '^//' memdump.txt | xxd -ps -c 2 -r > memdump.bin
|
||||||
|
|
||||||
${VVP} : ${SOURCES} ${INCLUDES}
|
${VVP} : ${SOURCES} ${INCLUDES}
|
||||||
iverilog -g2012 ${SOURCES} -o $@
|
iverilog -g2012 ${SOURCES} -o $@
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
[*]
|
[*]
|
||||||
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
|
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
|
||||||
[*] Fri Feb 10 01:43:01 2023
|
[*] Tue Feb 14 12:39:46 2023
|
||||||
[*]
|
[*]
|
||||||
[dumpfile] "/home/user/UNI_DATA/COMS30046_2022_TB-2/projects/9086/cpu/test.lx2"
|
[dumpfile] "/home/user/UNI_DATA/COMS30046_2022_TB-2/projects/9086/cpu/test.lx2"
|
||||||
[dumpfile_mtime] "Fri Feb 10 01:42:12 2023"
|
[dumpfile_mtime] "Tue Feb 14 12:37:32 2023"
|
||||||
[dumpfile_size] 1058
|
[dumpfile_size] 1922
|
||||||
[savefile] "/home/user/UNI_DATA/COMS30046_2022_TB-2/projects/9086/cpu/gtkwave_savefile.gtkw"
|
[savefile] "/home/user/UNI_DATA/COMS30046_2022_TB-2/projects/9086/cpu/gtkwave_savefile.gtkw"
|
||||||
[timestart] 0
|
[timestart] 0
|
||||||
[size] 1438 1059
|
[size] 1438 1059
|
||||||
[pos] -1 -1
|
[pos] -1 -1
|
||||||
*-21.795050 6163000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
*-23.795050 41712000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||||
[treeopen] tb.
|
[treeopen] tb.
|
||||||
[treeopen] tb.p.
|
[treeopen] tb.p.
|
||||||
[sst_width] 221
|
[sst_width] 221
|
||||||
@ -19,18 +19,17 @@
|
|||||||
@28
|
@28
|
||||||
tb.p.clock[0]
|
tb.p.clock[0]
|
||||||
tb.p.reset[0]
|
tb.p.reset[0]
|
||||||
tb.p.state[3:0]
|
tb.p.state[4:0]
|
||||||
@22
|
@22
|
||||||
tb.p.external_address_bus[19:0]
|
tb.p.external_address_bus[19:0]
|
||||||
tb.p.external_data_bus[15:0]
|
tb.p.external_data_bus[15:0]
|
||||||
tb.p.CIR[15:0]
|
tb.p.CIR[15:0]
|
||||||
@28
|
tb.p.PARAM1[15:0]
|
||||||
tb.p.EXCEPTION[0]
|
tb.p.PARAM2[15:0]
|
||||||
@22
|
|
||||||
tb.p.ADDER16_1.A[15:0]
|
|
||||||
tb.p.ADDER16_1.B[15:0]
|
|
||||||
tb.p.ADDER16_1.OUT[15:0]
|
|
||||||
@29
|
@29
|
||||||
tb.p.reg_write[0]
|
tb.p.read[0]
|
||||||
|
@28
|
||||||
|
tb.p.write[0]
|
||||||
|
tb.p.ERROR[0]
|
||||||
[pattern_trace] 1
|
[pattern_trace] 1
|
||||||
[pattern_trace] 0
|
[pattern_trace] 0
|
||||||
|
@ -17,7 +17,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/>. */
|
||||||
|
|
||||||
module rom(input [19:0] address,output wire [15:0] data ,input rd,input cs);
|
module mem(input [19:0] address,inout wire [15:0] data ,input rd,input wr,input cs);
|
||||||
reg [15:0] memory [0:599];
|
reg [15:0] memory [0:599];
|
||||||
initial begin
|
initial begin
|
||||||
string boot_code;
|
string boot_code;
|
||||||
@ -25,5 +25,11 @@ initial begin
|
|||||||
boot_code="boot_code.txt";
|
boot_code="boot_code.txt";
|
||||||
$readmemh(boot_code, memory);
|
$readmemh(boot_code, memory);
|
||||||
end
|
end
|
||||||
|
|
||||||
assign data = !rd & !cs ? memory[address]: 'hz;
|
assign data = !rd & !cs ? memory[address]: 'hz;
|
||||||
|
|
||||||
|
always @(negedge wr) begin
|
||||||
|
memory[address]=data;
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -18,26 +18,39 @@
|
|||||||
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/>. */
|
||||||
|
|
||||||
`define PROC_HALT_STATE 4'b0000
|
`define PROC_STATE_BITS 5
|
||||||
|
|
||||||
|
|
||||||
|
`define PROC_HALT_STATE 5'b00000
|
||||||
|
|
||||||
/*INSTRUCTION FETCH STATE*/
|
/*INSTRUCTION FETCH STATE*/
|
||||||
`define PROC_IF_STATE_ENTRY 4'b0001
|
`define PROC_IF_STATE_ENTRY 5'b00001
|
||||||
`define PROC_IF_WRITE_CIR 4'b0010
|
`define PROC_IF_WRITE_CIR 5'b00010
|
||||||
`define PROC_IF_STATE_EXTRA_FETCH_SET 4'b0011
|
`define PROC_IF_STATE_EXTRA_FETCH_SET 5'b00011
|
||||||
`define PROC_IF_STATE_EXTRA_FETCH 4'b1111 /******/
|
`define PROC_IF_STATE_EXTRA_FETCH 5'b00100
|
||||||
|
|
||||||
/*DECODE SATE*/
|
/*DECODE SATE*/
|
||||||
`define PROC_DE_STATE_ENTRY 4'b0100
|
`define PROC_DE_STATE_ENTRY 5'b01000
|
||||||
`define PROC_DE_LOAD_16_PARAM 4'b0101
|
`define PROC_DE_LOAD_16_PARAM 5'b01001
|
||||||
`define PROC_DE_LOAD_16_EXTRA_FETCH_SET 4'b0110
|
`define PROC_DE_LOAD_16_EXTRA_FETCH_SET 5'b01010
|
||||||
`define PROC_DE_LOAD_16_EXTRA_FETCH 4'b0111
|
`define PROC_DE_LOAD_16_EXTRA_FETCH 5'b01011
|
||||||
|
|
||||||
/*MEM/IO READ*/
|
/*MEM/IO READ*/
|
||||||
`define RPOC_MEMIO_READ 4'b1100
|
`define RPOC_MEMIO_READ 5'b10000
|
||||||
`define PROC_MEMIO_SETADDR 4'b1101
|
`define PROC_MEMIO_READ_SETADDR 5'b10001
|
||||||
`define PROC_MEMIO_GET_ALIGNED_DATA 4'b1110 /* :) */
|
`define PROC_MEMIO_GET_ALIGNED_DATA 5'b10010 /* :) */
|
||||||
`define PROC_MEMIO_GET_UNALIGNED_DATA 4'b1010 /* :( */
|
`define PROC_MEMIO_GET_UNALIGNED_DATA 5'b10011 /* :( */
|
||||||
|
|
||||||
/*EXECUTE STATE*/
|
/*EXECUTE STATE*/
|
||||||
`define PROC_EX_STATE_ENTRY 4'b1000
|
`define PROC_EX_STATE_ENTRY 5'b11000
|
||||||
`define PROC_EX_STATE_EXIT 4'b1001
|
`define PROC_EX_STATE_EXIT 5'b11001
|
||||||
|
|
||||||
|
/*MEM/IO WRITE*/
|
||||||
|
`define PROC_MEMIO_WRITE 5'b10100
|
||||||
|
//`define PROC_MEMIO_WRITE_SETADDR 5'b10101
|
||||||
|
`define PROC_MEMIO_PUT_ALIGNED_DATA 5'b10101
|
||||||
|
`define PROC_MEMIO_PUT_UNALIGNED_DATA 5'b10110
|
||||||
|
`define PROC_MEMIO_PUT_BYTE 5'b10111
|
||||||
|
`define PROC_MEMIO_PUT_BYTE_STOP_READ 5'b11110 /****/
|
||||||
|
`define PROC_MEMIO_PUT_BYTE_WRITE 5'b11111 /****/
|
||||||
|
|
||||||
|
133
cpu/processor.v
133
cpu/processor.v
@ -34,9 +34,13 @@ endmodule
|
|||||||
|
|
||||||
module processor ( 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 HALT,output reg ERROR);
|
module processor ( 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 HALT,output reg ERROR);
|
||||||
|
|
||||||
|
/*if we don't read, output the register to have the bus stable by the write falling edge*/
|
||||||
|
reg [15:0] data_bus_output_register;
|
||||||
|
assign external_data_bus=read?data_bus_output_register:'hz;
|
||||||
|
|
||||||
/*** Global Definitions ***/
|
/*** Global Definitions ***/
|
||||||
// State
|
// State
|
||||||
reg [3:0] state;
|
reg [`PROC_STATE_BITS-1:0] state;
|
||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
reg [19:0] ProgCount;
|
reg [19:0] ProgCount;
|
||||||
@ -44,8 +48,8 @@ reg [15:0] CIR;
|
|||||||
reg [15:0] PARAM1;
|
reg [15:0] PARAM1;
|
||||||
reg [15:0] PARAM2;
|
reg [15:0] PARAM2;
|
||||||
reg unaligned_access;
|
reg unaligned_access;
|
||||||
reg [1:0]IN_MOD;
|
reg [1:0]MOD;
|
||||||
reg [2:0]IN_RM;
|
reg [2:0]RM;
|
||||||
reg Wbit;
|
reg Wbit;
|
||||||
reg [15:0]FLAGS;
|
reg [15:0]FLAGS;
|
||||||
/* . . . . O D I T S Z . A . P . C */
|
/* . . . . O D I T S Z . A . P . C */
|
||||||
@ -69,6 +73,7 @@ reg [15:0]FLAGS;
|
|||||||
// D - Direction flag : 1: string instructions decrement 0: they increment
|
// D - Direction flag : 1: string instructions decrement 0: they increment
|
||||||
//
|
//
|
||||||
// O - Overflow flag : set on arithmetic overflow
|
// O - Overflow flag : set on arithmetic overflow
|
||||||
|
reg [15:0] BYTE_WRITE_TEMP_REG;//we read 16bits here if we want to change just 8 and leave the rest
|
||||||
|
|
||||||
|
|
||||||
// Execution units
|
// Execution units
|
||||||
@ -91,7 +96,7 @@ always @(negedge reset) begin
|
|||||||
@(posedge reset)
|
@(posedge reset)
|
||||||
@(negedge clock);
|
@(negedge clock);
|
||||||
state=`PROC_IF_STATE_ENTRY;
|
state=`PROC_IF_STATE_ENTRY;
|
||||||
IN_MOD=2'b11;
|
MOD=2'b11;
|
||||||
ERROR=0;
|
ERROR=0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -134,7 +139,7 @@ ALU ALU(ALU_1A,ALU_1B,ALU_1OE,ALU_1O,ALU_1OP,ALU_FLAGS,Wbit);
|
|||||||
|
|
||||||
/*** Processor stages ***/
|
/*** Processor stages ***/
|
||||||
|
|
||||||
`define invalid_instruction state=`PROC_IF_STATE_ENTRY;ERROR=1;IN_MOD=2'b11;
|
`define invalid_instruction state=`PROC_IF_STATE_ENTRY;ERROR=1;MOD=2'b11;
|
||||||
`define start_aligning_instruction if(unaligned_access==0)begin ProgCount=ProgCount+1; external_address_bus <= ProgCount; end /*we normally don't advance PC in case of singly byte unaligning instructions leaving us with two instructions in one read so do that here*/
|
`define start_aligning_instruction if(unaligned_access==0)begin ProgCount=ProgCount+1; external_address_bus <= ProgCount; end /*we normally don't advance PC in case of singly byte unaligning instructions leaving us with two instructions in one read so do that here*/
|
||||||
`define start_unaligning_instruction unaligned_access=~unaligned_access;
|
`define start_unaligning_instruction unaligned_access=~unaligned_access;
|
||||||
|
|
||||||
@ -156,6 +161,50 @@ always @(negedge clock) begin
|
|||||||
end
|
end
|
||||||
`PROC_EX_STATE_EXIT:begin
|
`PROC_EX_STATE_EXIT:begin
|
||||||
case(out_sel)
|
case(out_sel)
|
||||||
|
3'b000,
|
||||||
|
3'b001,
|
||||||
|
3'b010 : begin
|
||||||
|
case (RM) /* Duplicate code with write... */
|
||||||
|
3'b000:begin
|
||||||
|
/*[BX]+[SI]*/
|
||||||
|
`invalid_instruction
|
||||||
|
end
|
||||||
|
3'b001:begin
|
||||||
|
/*[BX]+[SI]*/
|
||||||
|
`invalid_instruction
|
||||||
|
end
|
||||||
|
3'b010:begin
|
||||||
|
/*[BP]+[SI]*/
|
||||||
|
`invalid_instruction
|
||||||
|
end
|
||||||
|
3'b011:begin
|
||||||
|
/*[BP]+[DI]*/
|
||||||
|
`invalid_instruction
|
||||||
|
end
|
||||||
|
3'b100:begin
|
||||||
|
/*[SI]*/
|
||||||
|
reg_read_addr=4'b1110;
|
||||||
|
reg_read_oe=0;
|
||||||
|
state=`PROC_MEMIO_WRITE;
|
||||||
|
end
|
||||||
|
3'b101:begin
|
||||||
|
/*[DI]*/
|
||||||
|
reg_read_addr=4'b1111;
|
||||||
|
reg_read_oe=0;
|
||||||
|
state=`PROC_MEMIO_WRITE;
|
||||||
|
end
|
||||||
|
3'b110:begin
|
||||||
|
/*d16 */
|
||||||
|
`invalid_instruction
|
||||||
|
end
|
||||||
|
3'b111:begin
|
||||||
|
/*[BX]*/
|
||||||
|
reg_read_addr=4'b1011;
|
||||||
|
reg_read_oe=0;
|
||||||
|
state=`PROC_MEMIO_WRITE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
3'b011:begin
|
3'b011:begin
|
||||||
reg_write_we=0;
|
reg_write_we=0;
|
||||||
state=`PROC_IF_STATE_ENTRY;
|
state=`PROC_IF_STATE_ENTRY;
|
||||||
@ -177,10 +226,18 @@ always @(negedge clock) begin
|
|||||||
external_address_bus = ProgCount;
|
external_address_bus = ProgCount;
|
||||||
state=`PROC_DE_LOAD_16_EXTRA_FETCH;
|
state=`PROC_DE_LOAD_16_EXTRA_FETCH;
|
||||||
end
|
end
|
||||||
`PROC_MEMIO_SETADDR:begin
|
`PROC_MEMIO_READ_SETADDR:begin
|
||||||
external_address_bus = {1'b0,reg_read_data[15:1]};
|
external_address_bus = {1'b0,reg_read_data[15:1]};
|
||||||
state=reg_read_data[0:0]?`PROC_MEMIO_GET_UNALIGNED_DATA:`PROC_MEMIO_GET_ALIGNED_DATA;
|
state=reg_read_data[0:0]?`PROC_MEMIO_GET_UNALIGNED_DATA:`PROC_MEMIO_GET_ALIGNED_DATA;
|
||||||
end
|
end
|
||||||
|
`PROC_MEMIO_PUT_BYTE:begin
|
||||||
|
BYTE_WRITE_TEMP_REG=external_data_bus;
|
||||||
|
state=`PROC_MEMIO_PUT_BYTE_STOP_READ;
|
||||||
|
end
|
||||||
|
`PROC_MEMIO_PUT_BYTE_WRITE:begin
|
||||||
|
write=0;
|
||||||
|
state=`PROC_IF_STATE_ENTRY;
|
||||||
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -225,7 +282,7 @@ always @(posedge clock) begin
|
|||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
else
|
else
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
IN_MOD=2'b11;
|
MOD=2'b11;
|
||||||
in1_sel=2'b00;
|
in1_sel=2'b00;
|
||||||
in2_sel=2'b01;
|
in2_sel=2'b01;
|
||||||
out_sel=3'b011;
|
out_sel=3'b011;
|
||||||
@ -252,7 +309,7 @@ always @(posedge clock) begin
|
|||||||
/* 1 0 0 0 0 0 S W | MOD 0 0 0 R/M | < DISP LO > | < DISP HI > | DATA | DATA if W | */
|
/* 1 0 0 0 0 0 S W | MOD 0 0 0 R/M | < DISP LO > | < DISP HI > | DATA | DATA if W | */
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
IN_MOD=2'b11;
|
MOD=2'b11;
|
||||||
in1_sel=2'b00;
|
in1_sel=2'b00;
|
||||||
in2_sel=2'b01;
|
in2_sel=2'b01;
|
||||||
out_sel={1'b0,CIR[7:6]};
|
out_sel={1'b0,CIR[7:6]};
|
||||||
@ -282,7 +339,7 @@ always @(posedge clock) begin
|
|||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
else
|
else
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
IN_MOD=2'b11;
|
MOD=2'b11;
|
||||||
in1_sel=2'b00;
|
in1_sel=2'b00;
|
||||||
in2_sel=2'b00;
|
in2_sel=2'b00;
|
||||||
out_sel=3'b011;
|
out_sel=3'b011;
|
||||||
@ -301,7 +358,7 @@ always @(posedge clock) begin
|
|||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
else
|
else
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
IN_MOD=2'b11;
|
MOD=2'b11;
|
||||||
in1_sel=2'b00;
|
in1_sel=2'b00;
|
||||||
in2_sel=2'b00;
|
in2_sel=2'b00;
|
||||||
out_sel=3'b011;
|
out_sel=3'b011;
|
||||||
@ -316,13 +373,13 @@ always @(posedge clock) begin
|
|||||||
/* MOV - Reg/Mem to/from register */
|
/* MOV - Reg/Mem to/from register */
|
||||||
/* 1 0 0 0 1 0 D W | MOD REG REG | < DISP LO > | < DISP HI > |*/
|
/* 1 0 0 0 1 0 D W | MOD REG REG | < DISP LO > | < DISP HI > |*/
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
IN_MOD=CIR[7:6];
|
MOD=CIR[7:6];
|
||||||
IN_RM=CIR[2:0];
|
RM=CIR[2:0];
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
if(CIR[9:9] == 1)begin
|
if(CIR[9:9] == 1)begin
|
||||||
/* to reg */
|
/* to reg */
|
||||||
IN_MOD=CIR[7:6];
|
MOD=CIR[7:6];
|
||||||
if(IN_MOD==2'b11)begin
|
if(MOD==2'b11)begin
|
||||||
in1_sel=2'b01;
|
in1_sel=2'b01;
|
||||||
reg_read_addr=CIR[2:0];
|
reg_read_addr=CIR[2:0];
|
||||||
end else begin
|
end else begin
|
||||||
@ -339,7 +396,7 @@ always @(posedge clock) begin
|
|||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_1OP=`ALU_OP_ADD;
|
||||||
PARAM2=0;
|
PARAM2=0;
|
||||||
state=`PROC_DE_LOAD_16_PARAM;
|
state=`PROC_DE_LOAD_16_PARAM;
|
||||||
if ( IN_MOD == 2'b11 )
|
if ( MOD == 2'b11 )
|
||||||
state=`PROC_EX_STATE_ENTRY;
|
state=`PROC_EX_STATE_ENTRY;
|
||||||
else
|
else
|
||||||
state=`RPOC_MEMIO_READ;
|
state=`RPOC_MEMIO_READ;
|
||||||
@ -357,7 +414,7 @@ always @(posedge clock) begin
|
|||||||
in1_sel=2'b01;
|
in1_sel=2'b01;
|
||||||
in2_sel=2'b00;
|
in2_sel=2'b00;
|
||||||
out_sel=3'b011;
|
out_sel=3'b011;
|
||||||
IN_MOD=2'b11;
|
MOD=2'b11;
|
||||||
PARAM2=1;
|
PARAM2=1;
|
||||||
reg_read_addr={1'b1,CIR[10:8]};
|
reg_read_addr={1'b1,CIR[10:8]};
|
||||||
reg_write_addr={1'b1,CIR[10:8]};
|
reg_write_addr={1'b1,CIR[10:8]};
|
||||||
@ -378,14 +435,18 @@ always @(posedge clock) begin
|
|||||||
/* 1 1 1 1 1 1 1 W | MOD 0 0 0 R/M | < DISP LO> | < DISP HI> */
|
/* 1 1 1 1 1 1 1 W | MOD 0 0 0 R/M | < DISP LO> | < DISP HI> */
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
IN_MOD=CIR[7:6];
|
MOD=CIR[7:6];
|
||||||
in1_sel=2'b00;/* number 1 */
|
RM=CIR[2:0];
|
||||||
in2_sel=(CIR[7:6]==2'b11)? 2'b01 : 2'b00;
|
in1_sel=(MOD==2'b11)? 2'b01 : 2'b00;
|
||||||
out_sel={1'b0,CIR[7:6]};
|
in2_sel=2'b00;/* number 1 */
|
||||||
PARAM1=1;
|
out_sel={1'b0,MOD};
|
||||||
reg_read_addr={1'b0,CIR[2:0]};
|
PARAM2=1;
|
||||||
reg_write_addr={1'b0,CIR[2:0]};
|
|
||||||
|
/*in case MOD=11 */
|
||||||
|
reg_read_addr={1'b0,RM};
|
||||||
|
reg_write_addr={1'b0,RM};
|
||||||
reg_read_oe=0;
|
reg_read_oe=0;
|
||||||
|
|
||||||
ALU_1OE=0;
|
ALU_1OE=0;
|
||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_1OP=`ALU_OP_ADD;
|
||||||
if ( CIR[7:6] == 2'b11 )
|
if ( CIR[7:6] == 2'b11 )
|
||||||
@ -408,7 +469,7 @@ always @(posedge clock) begin
|
|||||||
/* HLT - Halt */
|
/* HLT - Halt */
|
||||||
/* 1 1 1 1 0 1 0 0 | */
|
/* 1 1 1 1 0 1 0 0 | */
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
IN_MOD=2'b11;
|
MOD=2'b11;
|
||||||
HALT=1;
|
HALT=1;
|
||||||
state=`PROC_HALT_STATE;
|
state=`PROC_HALT_STATE;
|
||||||
end
|
end
|
||||||
@ -430,7 +491,7 @@ always @(posedge clock) begin
|
|||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
else
|
else
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
IN_MOD=2'b11;
|
MOD=2'b11;
|
||||||
in1_sel=2'b00;
|
in1_sel=2'b00;
|
||||||
in2_sel=2'b01;
|
in2_sel=2'b01;
|
||||||
reg_read_addr={CIR[8:8],3'b000};
|
reg_read_addr={CIR[8:8],3'b000};
|
||||||
@ -530,7 +591,7 @@ always @(posedge clock) begin
|
|||||||
end
|
end
|
||||||
`RPOC_MEMIO_READ:begin
|
`RPOC_MEMIO_READ:begin
|
||||||
/*Decode MOD R/M, read the data and place it to PARAM1*/
|
/*Decode MOD R/M, read the data and place it to PARAM1*/
|
||||||
case (IN_RM)
|
case (RM)
|
||||||
3'b000:begin
|
3'b000:begin
|
||||||
/*[BX]+[SI]*/
|
/*[BX]+[SI]*/
|
||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
@ -551,13 +612,13 @@ always @(posedge clock) begin
|
|||||||
/*[SI]*/
|
/*[SI]*/
|
||||||
reg_read_addr=4'b1110;
|
reg_read_addr=4'b1110;
|
||||||
reg_read_oe=0;
|
reg_read_oe=0;
|
||||||
state=`PROC_MEMIO_SETADDR;
|
state=`PROC_MEMIO_READ_SETADDR;
|
||||||
end
|
end
|
||||||
3'b101:begin
|
3'b101:begin
|
||||||
/*[DI]*/
|
/*[DI]*/
|
||||||
reg_read_addr=4'b1111;
|
reg_read_addr=4'b1111;
|
||||||
reg_read_oe=0;
|
reg_read_oe=0;
|
||||||
state=`PROC_MEMIO_SETADDR;
|
state=`PROC_MEMIO_READ_SETADDR;
|
||||||
end
|
end
|
||||||
3'b110:begin
|
3'b110:begin
|
||||||
/*d16 */
|
/*d16 */
|
||||||
@ -567,10 +628,10 @@ always @(posedge clock) begin
|
|||||||
/*[BX]*/
|
/*[BX]*/
|
||||||
reg_read_addr=4'b1011;
|
reg_read_addr=4'b1011;
|
||||||
reg_read_oe=0;
|
reg_read_oe=0;
|
||||||
state=`PROC_MEMIO_SETADDR;
|
state=`PROC_MEMIO_READ_SETADDR;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
if(IN_MOD!=2'b00)begin
|
if(MOD!=2'b00)begin
|
||||||
/*Actually check if 01 and add the 8bits or if 10 add the 16bits ....*/
|
/*Actually check if 01 and add the 8bits or if 10 add the 16bits ....*/
|
||||||
`invalid_instruction;
|
`invalid_instruction;
|
||||||
end
|
end
|
||||||
@ -593,6 +654,18 @@ always @(posedge clock) begin
|
|||||||
FLAGS[7:0] = ALU_FLAGS[7:0];
|
FLAGS[7:0] = ALU_FLAGS[7:0];
|
||||||
state=`PROC_EX_STATE_EXIT;
|
state=`PROC_EX_STATE_EXIT;
|
||||||
end
|
end
|
||||||
|
`PROC_MEMIO_WRITE:begin
|
||||||
|
external_address_bus = {1'b0,reg_read_data[15:1]};
|
||||||
|
state = (Wbit==0) ? `PROC_MEMIO_PUT_BYTE : (reg_read_data[0:0]?`PROC_MEMIO_PUT_UNALIGNED_DATA:`PROC_MEMIO_PUT_ALIGNED_DATA) ;
|
||||||
|
end
|
||||||
|
`PROC_MEMIO_PUT_BYTE_STOP_READ:begin
|
||||||
|
read=1;
|
||||||
|
state=`PROC_MEMIO_PUT_BYTE_WRITE;
|
||||||
|
if(reg_read_data[0:0]==0)
|
||||||
|
data_bus_output_register={ALU_1O[7:0],BYTE_WRITE_TEMP_REG[7:0]};
|
||||||
|
else
|
||||||
|
data_bus_output_register={BYTE_WRITE_TEMP_REG[15:8],ALU_1O[7:0]};
|
||||||
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ wire rd,wr,romcs,HALT;
|
|||||||
wire ERROR;
|
wire ERROR;
|
||||||
|
|
||||||
processor p(clock,reset,address_bus,data_bus,rd,wr,HALT,ERROR);
|
processor p(clock,reset,address_bus,data_bus,rd,wr,HALT,ERROR);
|
||||||
rom bootrom(address_bus,data_bus,rd,romcs);
|
mem sysmem(address_bus,data_bus,rd,wr,romcs);
|
||||||
|
|
||||||
`define CPU_SPEED 1000
|
`define CPU_SPEED 1000
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ end
|
|||||||
|
|
||||||
always @(posedge HALT) begin
|
always @(posedge HALT) begin
|
||||||
$display("Processor halted.\nCycles run for: %d",cycles);
|
$display("Processor halted.\nCycles run for: %d",cycles);
|
||||||
$writememh("memdump.txt", bootrom.memory);
|
$writememh("memdump.txt", sysmem.memory);
|
||||||
#(`CPU_SPEED) //Just for the waveform
|
#(`CPU_SPEED) //Just for the waveform
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
@ -59,7 +59,7 @@ end
|
|||||||
always @(posedge ERROR) begin
|
always @(posedge ERROR) begin
|
||||||
clk_enable <= 0;
|
clk_enable <= 0;
|
||||||
$display("PROCESSOR RUN INTO AN ERROR.\nCycles run for: %d",cycles);
|
$display("PROCESSOR RUN INTO AN ERROR.\nCycles run for: %d",cycles);
|
||||||
$writememh("memdump.txt", bootrom.memory);
|
$writememh("memdump.txt", sysmem.memory);
|
||||||
#(`CPU_SPEED) //Just for the waveform
|
#(`CPU_SPEED) //Just for the waveform
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user