Implemented PUSH instruction, fixed register addressing bug and a RET bug
This commit is contained in:
parent
a189da249c
commit
abee49d6c3
@ -273,7 +273,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* DEC - Register/Memory */
|
/* DEC - Register/Memory */
|
||||||
/* 1 1 1 1 1 1 1 W | MOD 0 0 1 R/M | < DISP LO> | < DISP HI> */
|
/* 1 1 1 1 1 1 1 W | MOD 0 0 1 R/M | < DISP LO> | < DISP HI> */
|
||||||
seq_addr_entry=`UCODE_NO_INSTRUCTION;
|
seq_addr_entry=`UCODE_NO_INSTRUCTION;
|
||||||
has_operands=1;
|
has_operands=0;
|
||||||
opcode_size=1;
|
opcode_size=1;
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
@ -414,7 +414,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
end
|
end
|
||||||
next_state=`PROC_IF_STATE_ENTRY;
|
next_state=`PROC_IF_STATE_ENTRY;
|
||||||
end
|
end
|
||||||
11'b11101000_xxx:begin
|
11'b1110_1000_xxx:begin
|
||||||
/* CALL - Direct call within segment */
|
/* CALL - Direct call within segment */
|
||||||
/* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/
|
/* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/
|
||||||
|
|
||||||
@ -427,7 +427,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
PARAM2=2; //substract from sp
|
PARAM2=2; //substract from sp
|
||||||
seq_addr_entry=`UCODE_CALL_ENTRY;
|
seq_addr_entry=`UCODE_CALL_ENTRY;
|
||||||
end
|
end
|
||||||
11'b11000011_xxx:begin
|
11'b1100_0011_xxx:begin
|
||||||
/* RET - Return from call within segment */
|
/* RET - Return from call within segment */
|
||||||
/* | 1 1 0 0 0 0 1 1 | */
|
/* | 1 1 0 0 0 0 1 1 | */
|
||||||
|
|
||||||
@ -442,10 +442,10 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
has_operands=1;
|
has_operands=1;
|
||||||
Wbit=1;
|
Wbit=1;
|
||||||
Sbit=0;
|
Sbit=0;
|
||||||
PARAM2=2;
|
PARAM1=2;
|
||||||
seq_addr_entry=`UCODE_RET_ENTRY;
|
seq_addr_entry=`UCODE_RET_ENTRY;
|
||||||
end
|
end
|
||||||
11'b1010101x_xxx:begin
|
11'b1010_101x_xxx:begin
|
||||||
/* STOS - Write byte/word to [DI] and increment accordingly */
|
/* STOS - Write byte/word to [DI] and increment accordingly */
|
||||||
/* | 1 0 1 0 1 0 1 W | */
|
/* | 1 0 1 0 1 0 1 W | */
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
@ -457,6 +457,18 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
seq_addr_entry=`UCODE_STOS_ENTRY;
|
seq_addr_entry=`UCODE_STOS_ENTRY;
|
||||||
PARAM2=(Wbit==1)?2:1;
|
PARAM2=(Wbit==1)?2:1;
|
||||||
end
|
end
|
||||||
|
11'b0101_0xxx_xxx:begin
|
||||||
|
/* PUSH - SP-=2; [SP]=REG */
|
||||||
|
/* | 0 1 0 1 0 REG | */
|
||||||
|
`start_unaligning_instruction
|
||||||
|
opcode_size=0;
|
||||||
|
has_operands=0;
|
||||||
|
Wbit=1;
|
||||||
|
Sbit=0;
|
||||||
|
PARAM2=2;
|
||||||
|
reg_read_port2_addr={1'b1,CIR[10:8]};
|
||||||
|
seq_addr_entry=`UCODE_PUSH_ENTRY;
|
||||||
|
end
|
||||||
default:begin
|
default:begin
|
||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
end
|
end
|
||||||
@ -487,9 +499,13 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B;
|
3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B;
|
||||||
3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE;
|
3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE;
|
||||||
endcase
|
endcase
|
||||||
reg_read_port1_addr=ucode_data[25:22];
|
if(ucode_data[33:33]==0)
|
||||||
IN_MOD =ucode_data[28:26];
|
reg_read_port1_addr=ucode_data[25:22];
|
||||||
reg_read_port2_addr=ucode_data[32:29];
|
IN_MOD=ucode_data[28:26];
|
||||||
|
if(ucode_data[34:34]==0)
|
||||||
|
reg_read_port2_addr=ucode_data[32:29];
|
||||||
|
if(ucode_data[36:36]==1)
|
||||||
|
Wbit=ucode_data[35:35];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ always @(negedge clock) begin
|
|||||||
* be done by decode at the end*/
|
* be done by decode at the end*/
|
||||||
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
||||||
unaligned_access=unaligning_instruction^unaligned_access;
|
unaligned_access=unaligning_instruction^unaligned_access;
|
||||||
case(OUT_MOD) /*TODO: use RM*/
|
case(OUT_MOD)
|
||||||
3'b000,
|
3'b000,
|
||||||
3'b001,
|
3'b001,
|
||||||
3'b010 : begin
|
3'b010 : begin
|
||||||
@ -507,7 +507,7 @@ always @(posedge clock) begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
`PROC_EX_STATE_ENTRY:begin
|
`PROC_EX_STATE_ENTRY:begin
|
||||||
FLAGS[7:0] = ALU_1FLAGS[7:0];
|
FLAGS[7:0] = ALU_1FLAGS[7:0]; //TODO, we should probably move all the ...STATE_EXIT stuff here
|
||||||
state=`PROC_EX_STATE_EXIT;
|
state=`PROC_EX_STATE_EXIT;
|
||||||
end
|
end
|
||||||
`PROC_MEMIO_WRITE:begin
|
`PROC_MEMIO_WRITE:begin
|
||||||
|
@ -32,11 +32,13 @@ input write_port1_we;
|
|||||||
|
|
||||||
reg [15:0] registers [7:0];
|
reg [15:0] registers [7:0];
|
||||||
|
|
||||||
assign read_port1_data = ( read_port1_addr[3:3] ? registers[read_port1_addr[2:0]] :
|
assign read_port1_data[15:8] = read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][15:8] : 8'hz ;
|
||||||
( read_port1_addr[2:2] ? {8'b0,registers[read_port1_addr[2:0]][15:8]} : {8'b0,registers[read_port1_addr[2:0]][7:0]} ) );
|
assign read_port1_data[7:0] = ( read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][7:0] :
|
||||||
|
( read_port1_addr[2:2] ? {8'b0,registers[read_port1_addr[1:0]][15:8]} : {8'b0,registers[read_port1_addr[1:0]][7:0]} ) );
|
||||||
|
|
||||||
assign read_port2_data = ( read_port2_addr[3:3] ? registers[read_port2_addr[2:0]] :
|
assign read_port2_data[15:8] = read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][15:8] : 8'hz ;
|
||||||
( read_port2_addr[2:2] ? {8'b0,registers[read_port2_addr[2:0]][15:8]} : {8'b0,registers[read_port2_addr[2:0]][7:0]} ) );
|
assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][7:0] :
|
||||||
|
( read_port2_addr[2:2] ? {8'b0,registers[read_port2_addr[1:0]][15:8]} : {8'b0,registers[read_port2_addr[1:0]][7:0]} ) );
|
||||||
|
|
||||||
`ifdef DEBUG_REG_WRITES
|
`ifdef DEBUG_REG_WRITES
|
||||||
string debug_name;
|
string debug_name;
|
||||||
|
@ -17,6 +17,13 @@
|
|||||||
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/>. */
|
||||||
|
|
||||||
|
//wbo: Wbit overwrite, {VALUE,ENABLE}. ex 11 would force one, 10 wouldn't do anything
|
||||||
|
//
|
||||||
|
//krs: Keep registers, selects weather the register port 1 and/or 2
|
||||||
|
// addresses is set on that microcoded instruction or kept as it
|
||||||
|
// was before allowing for registers to be parameterised.
|
||||||
|
// {Register_port2, Register_port1}
|
||||||
|
//
|
||||||
//rr2: reg_read_port2_addr
|
//rr2: reg_read_port2_addr
|
||||||
//
|
//
|
||||||
//imd: IN_MOD
|
//imd: IN_MOD
|
||||||
@ -50,19 +57,24 @@
|
|||||||
|
|
||||||
@000 0000_000_000__00__00_0000__00_000000
|
@000 0000_000_000__00__00_0000__00_000000
|
||||||
|
|
||||||
// 32 28 25 21 18 15 13 11 7 5 0
|
// 36 34 32 28 25 21 18 15 13 11 7 5 0
|
||||||
// CALL
|
// CALL
|
||||||
// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
@001 0000_011_1100_001_011__00__01_1100__01_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
|
@001 _00_00_0000_011_1100_001_011__00__01_1100__01_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
|
||||||
@002 0000_011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
|
@002 _00_00_0000_011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
|
||||||
@003 0000_011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
|
@003 _00_00_0000_011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
|
||||||
|
|
||||||
// RET
|
// RET
|
||||||
// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
@004 0000_110_zzzz_000_101__00__11_zzzz__11_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2)
|
@004 _00_00_0000_110_zzzz_000_101__00__11_zzzz__11_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2)
|
||||||
@005 0000_011_1100_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
|
@005 _00_00_1100_011_0000_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
|
||||||
|
|
||||||
// STOS
|
// STOS
|
||||||
// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
@006 1000_011_zzzz_000_000__01__11_zzzz__00_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI]
|
@006 _00_00_1000_011_zzzz_000_000__01__11_zzzz__00_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI]
|
||||||
@007 zzzz_011_1111_000_011__00__01_1111__00_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI
|
@007 _11_00_zzzz_011_1111_000_011__00__01_1111__00_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI
|
||||||
|
|
||||||
|
// PUSH
|
||||||
|
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
|
@008 _00_10_0000_011_1100_001_011__00__01_1100__00_001001 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
|
||||||
|
@009 _00_10_0000_011_zzzz_000_110__01__11_zzzz__00_000000 // ALU_1: 0 ALU_2: REG ALU_OP:ADD ALU_out: [SP]
|
||||||
|
@ -18,11 +18,12 @@
|
|||||||
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 UCODE_ADDR_BITS 5
|
`define UCODE_ADDR_BITS 5
|
||||||
`define UCODE_DATA_BITS 33
|
`define UCODE_DATA_BITS 37
|
||||||
`define UCODE_SIZE 8
|
`define UCODE_SIZE 10
|
||||||
|
|
||||||
/* DEFINE ADDRESSES IN THE MICROCODE */
|
/* DEFINE ADDRESSES IN THE MICROCODE */
|
||||||
`define UCODE_NO_INSTRUCTION 5'b00000
|
`define UCODE_NO_INSTRUCTION 5'b00000
|
||||||
`define UCODE_CALL_ENTRY 5'b00001
|
`define UCODE_CALL_ENTRY 5'b00001
|
||||||
`define UCODE_RET_ENTRY 5'b00100
|
`define UCODE_RET_ENTRY 5'b00100
|
||||||
`define UCODE_STOS_ENTRY 5'b00110
|
`define UCODE_STOS_ENTRY 5'b00110
|
||||||
|
`define UCODE_PUSH_ENTRY 5'b01000
|
||||||
|
Loading…
Reference in New Issue
Block a user