Switched some assignments in decode.v to non-blocking which fixed a seemingly unrelated bug with incrementing the accumulator, added some more working test code in colored_led.asm and did some semantic changes as per yosys suggestions

This commit is contained in:
(Tim) Efthimis Kritikos 2023-11-12 02:54:41 +00:00
parent 4c130a8d63
commit f471b305d8
2 changed files with 105 additions and 95 deletions

View File

@ -12,7 +12,14 @@ JNZ DELAY11
MOV AL,#0x01
out byte #0xB0
MOV AL,#0x48
MOV SI,#RESERVED
MOV DI,#RESERVED
MOV AL,#0x68 ; 'h'
MOV [DI],AL
MOV AL,#0x00
MOV AL,[SI]
out byte #0xA5
MOV AL,#0x65
out byte #0xA5
@ -39,6 +46,8 @@ out byte #0xB0
MOV AX,#0x0100
JMP AX
RESERVED: DB 0x48 ; 'H'
.ORG 0xFFF0
MOV AX,#0x0100
JMP AX

View File

@ -260,8 +260,8 @@ microcode ucode(seq_addr_input,ucode_data);
//opcode_size=0 would be to set PARAM1 here instead of sending execution over
//to EXEC_DE_LOAD_8_PARAM
`define normal_instruction seq_addr_entry<=`UCODE_NO_INSTRUCTION;ERROR<=`ERR_NO_ERROR;HALT<=0;MEM_OR_IO=0;
`define normal_microcoded ERROR<=`ERR_NO_ERROR;HALT<=0;MEM_OR_IO=0;
`define normal_instruction seq_addr_entry<=`UCODE_NO_INSTRUCTION;ERROR<=`ERR_NO_ERROR;HALT<=0;MEM_OR_IO<=0;
`define normal_microcoded ERROR<=`ERR_NO_ERROR;HALT<=0;MEM_OR_IO<=0;
reg [1:0] PARAM_ACTION;
`define NO_LOAD 2'b00
@ -285,14 +285,15 @@ always @( posedge clock ) begin
/* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/
opcode_size=0;
Wbit=INSTRUCTION[24:24];
Sbit=0;
IN_MOD=3'b011;
in_alu_sel1=2'b00;
in_alu_sel2=2'b01;
OUT_MOD=3'b011;
MEM_OR_IO=0;
reg_read_port2_addr={Wbit,3'b000};
reg_write_addr={Wbit,3'b000};
ALU_OP=`ALU_OP_ADD;
MEM_OR_IO<=0;
reg_read_port2_addr<={Wbit,3'b000};
reg_write_addr<={Wbit,3'b000};
ALU_OP<=`ALU_OP_ADD;
memio_address_select=0;
if(Wbit)
PARAM_ACTION=`LOAD_16;
@ -315,13 +316,13 @@ always @( posedge clock ) begin
in_alu_sel1=2'b00;
if(IN_MOD==3'b011)begin
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,RM};
reg_write_addr={Wbit,RM};
reg_read_port2_addr<={Wbit,RM};
reg_write_addr<={Wbit,RM};
end else begin
in_alu_sel2=2'b00;
end
OUT_MOD=IN_MOD;
MEM_OR_IO=0;
MEM_OR_IO<=0;
memio_address_select=0;
case({Sbit,Wbit}) // TODO: Isn't this supposed to be just a LOAD_8?
2'b00,2'b11:begin
@ -335,8 +336,8 @@ always @( posedge clock ) begin
end
endcase
case(INSTRUCTION[21:19])
3'b000: ALU_OP=`ALU_OP_ADD;
3'b101: ALU_OP=`ALU_OP_SUB_REVERSE;
3'b000: ALU_OP<=`ALU_OP_ADD;
3'b101: ALU_OP<=`ALU_OP_SUB_REVERSE;
default:begin
/*Should be impossible*/
`invalid_instruction
@ -358,13 +359,13 @@ always @( posedge clock ) begin
end
in_alu_sel1=2'b00;
OUT_MOD=3'b100;
MEM_OR_IO=0;
ALU_OP=`ALU_OP_SUB_REVERSE;
MEM_OR_IO<=0;
ALU_OP<=`ALU_OP_SUB_REVERSE;
memio_address_select=0;
if(IN_MOD==3'b011)begin
/*compare register with param*/
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,RM};
reg_read_port2_addr<={Wbit,RM};
next_state=`EXEC_WRITE_ENTRY;
end else begin
/*compare register indirect access
@ -389,14 +390,14 @@ always @( posedge clock ) begin
in_alu_sel1=2'b00;
in_alu_sel2=2'b00;
OUT_MOD=3'b011;
MEM_OR_IO=0;
reg_write_addr={Wbit,INSTRUCTION[26:24]};
MEM_OR_IO<=0;
reg_write_addr<={Wbit,INSTRUCTION[26:24]};
if(Wbit)
PARAM_ACTION=`LOAD_16;
else
PARAM_ACTION=`LOAD_8;
PARAM2=0;
ALU_OP=`ALU_OP_ADD;
ALU_OP<=`ALU_OP_ADD;
next_state=`EXEC_WRITE_ENTRY;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
@ -409,15 +410,15 @@ always @( posedge clock ) begin
RM=INSTRUCTION[18:16];
Wbit=INSTRUCTION[24:24];
in_alu_sel1=2'b00;
PARAM1=0;
MEM_OR_IO=0;
PARAM1<=0;
MEM_OR_IO<=0;
if(INSTRUCTION[25:25] == 1)begin
/* Mem/Reg to reg */
IN_MOD={1'b0,INSTRUCTION[23:22]};
if(IN_MOD==3'b011)begin
/*Reg to Reg*/
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,RM};
reg_read_port2_addr<={Wbit,RM};
next_state=`EXEC_WRITE_ENTRY;
end else begin
/*Mem to Reg*/
@ -425,7 +426,7 @@ always @( posedge clock ) begin
next_state=`EXEC_MEMIO_READ;
end
OUT_MOD=3'b011;
reg_write_addr={Wbit,INSTRUCTION[21:19]};
reg_write_addr<={Wbit,INSTRUCTION[21:19]};
end else begin
/* Reg to Mem/Reg */
IN_MOD=3'b011;
@ -433,16 +434,16 @@ always @( posedge clock ) begin
if(IN_MOD==3'b011)begin
/*Reg to Reg*/
in_alu_sel2=2'b01;
reg_write_addr={Wbit,RM};
reg_write_addr<={Wbit,RM};
next_state=`EXEC_WRITE_ENTRY;
end else begin
/*Reg to Mem*/
in_alu_sel2=2'b00;
next_state=`EXEC_DE_LOAD_REG_TO_PARAM;
end
reg_read_port2_addr={Wbit,INSTRUCTION[21:19]};
reg_read_port2_addr<={Wbit,INSTRUCTION[21:19]};
end
ALU_OP=`ALU_OP_ADD;
ALU_OP<=`ALU_OP_ADD;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
@ -458,15 +459,15 @@ always @( posedge clock ) begin
in_alu_sel1=2'b01;
in_alu_sel2=2'b00;
OUT_MOD=3'b011;
MEM_OR_IO=0;
MEM_OR_IO<=0;
IN_MOD=3'b011;
PARAM2=1;
reg_read_port1_addr={1'b1,INSTRUCTION[26:24]};
reg_write_addr={1'b1,INSTRUCTION[26:24]};
reg_read_port1_addr<={1'b1,INSTRUCTION[26:24]};
reg_write_addr<={1'b1,INSTRUCTION[26:24]};
if(INSTRUCTION[27:27]==0)
ALU_OP=`ALU_OP_ADD;
ALU_OP<=`ALU_OP_ADD;
else
ALU_OP=`ALU_OP_SUB;
ALU_OP<=`ALU_OP_SUB;
next_state=`EXEC_WRITE_ENTRY;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
@ -483,15 +484,15 @@ always @( posedge clock ) begin
RM=INSTRUCTION[18:16];
in_alu_sel2=(IN_MOD==3'b011)? 2'b01 : 2'b00;
in_alu_sel1=2'b00;/* number 1 */
PARAM1=1;
PARAM1<=16'd1;
OUT_MOD=IN_MOD;
MEM_OR_IO=0;
MEM_OR_IO<=0;
/*in case IN_MOD=011 */
reg_read_port2_addr={1'b0,RM};
reg_write_addr={1'b0,RM};
reg_read_port2_addr<={1'b0,RM};
reg_write_addr<={1'b0,RM};
ALU_OP=(INSTRUCTION[19:19]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD;
ALU_OP<=(INSTRUCTION[19:19]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD;
if ( IN_MOD == 3'b011 )
next_state=`EXEC_WRITE_ENTRY;
else
@ -507,7 +508,7 @@ always @( posedge clock ) begin
IN_MOD=3'b011;
HALT<=1;
ERROR<=`ERR_NO_ERROR;
MEM_OR_IO=0;
MEM_OR_IO<=0;
seq_addr_entry<=`UCODE_NO_INSTRUCTION;
next_state=`EXEC_WAIT;
DEPENDS_ON_PREVIOUS<=0;
@ -524,10 +525,10 @@ always @( posedge clock ) begin
IN_MOD=3'b011;
in_alu_sel1=2'b00;
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,3'b000};
reg_read_port2_addr<={Wbit,3'b000};
OUT_MOD=3'b100;
ALU_OP=`ALU_OP_SUB_REVERSE;
MEM_OR_IO=0;
ALU_OP<=`ALU_OP_SUB_REVERSE;
MEM_OR_IO<=0;
if(Wbit==1)
PARAM_ACTION=`LOAD_16;
else begin
@ -553,8 +554,8 @@ always @( posedge clock ) begin
in_alu_sel1=2'b10;
in_alu_sel2=2'b00;
PARAM2={{8{INSTRUCTION[23:23]}},INSTRUCTION[23:16]};
ALU_OP=`ALU_OP_ADD_SIGNED_B;
MEM_OR_IO=0;
ALU_OP<=`ALU_OP_ADD_SIGNED_B;
MEM_OR_IO<=0;
OUT_MOD=3'b101;
case(INSTRUCTION[27:25])
3'b000: begin
@ -613,9 +614,9 @@ always @( posedge clock ) begin
in_alu_sel1=2'b10;
in_alu_sel2=2'b00;
PARAM2={{8{INSTRUCTION[23:23]}},INSTRUCTION[23:16]};
ALU_OP=`ALU_OP_ADD_SIGNED_B;
ALU_OP<=`ALU_OP_ADD_SIGNED_B;
OUT_MOD=3'b101;
MEM_OR_IO=0;
MEM_OR_IO<=0;
next_state=`EXEC_WRITE_ENTRY;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
@ -643,7 +644,7 @@ always @( posedge clock ) begin
opcode_size=0;
Wbit=1;
Sbit=0;
PARAM1=2;
PARAM1<=2;
seq_addr_entry<=`UCODE_RET_ENTRY;
`normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
@ -669,7 +670,7 @@ always @( posedge clock ) begin
Wbit=1;
Sbit=0;
PARAM2=2;
reg_read_port2_addr={1'b1,INSTRUCTION[26:24]};
reg_read_port2_addr<={1'b1,INSTRUCTION[26:24]};
seq_addr_entry<=`UCODE_PUSH_ENTRY;
`normal_microcoded
memio_address_select=0;
@ -682,18 +683,18 @@ always @( posedge clock ) begin
Wbit=INSTRUCTION[24:24];
IN_MOD={1'b0,INSTRUCTION[23:22]};
RM={INSTRUCTION[18:16]};
MEM_OR_IO=0;
MEM_OR_IO<=0;
if(Wbit==1)begin
PARAM_ACTION=`LOAD_16;
end else begin
PARAM_ACTION=`LOAD_8;
end
in_alu_sel1=2'b00; /* PARAM1 */
ALU_OP=`ALU_OP_AND;
ALU_OP<=`ALU_OP_AND;
case(IN_MOD)
3'b011:begin
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,RM};
reg_read_port2_addr<={Wbit,RM};
next_state=`EXEC_WRITE_ENTRY;
end
default:begin
@ -713,7 +714,7 @@ always @( posedge clock ) begin
Wbit=INSTRUCTION[24:24];
IN_MOD=3'b011;
RM=3'b000;
MEM_OR_IO=0;
MEM_OR_IO<=0;
if(Wbit==1)begin
PARAM_ACTION=`LOAD_16;
end else begin
@ -721,9 +722,9 @@ always @( posedge clock ) begin
end
next_state=`EXEC_WRITE_ENTRY;
in_alu_sel1=2'b00; /* PARAM1 */
ALU_OP=`ALU_OP_AND;
ALU_OP<=`ALU_OP_AND;
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,RM};
reg_read_port2_addr<={Wbit,RM};
OUT_MOD=3'b100;/*NULL*/
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
@ -735,8 +736,8 @@ always @( posedge clock ) begin
opcode_size=0;
Wbit=1;
Sbit=0;
PARAM1=2;
reg_write_addr={1'b1,INSTRUCTION[26:24]};
PARAM1<=2;
reg_write_addr<={1'b1,INSTRUCTION[26:24]};
seq_addr_entry<=`UCODE_POP_ENTRY;
`normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
@ -749,17 +750,17 @@ always @( posedge clock ) begin
Wbit=1;
IN_MOD={1'b0,INSTRUCTION[23:22]};
RM=INSTRUCTION[18:16];
MEM_OR_IO=0;
MEM_OR_IO<=0;
in_alu_sel1=2'b11;
if (IN_MOD==3'b011)begin
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,RM};
reg_read_port2_addr<={Wbit,RM};
next_state=`EXEC_WRITE_ENTRY;
end else begin
in_alu_sel2=2'b00;
next_state=`EXEC_MEMIO_READ;
end
ALU_OP=`ALU_OP_ADD;
ALU_OP<=`ALU_OP_ADD;
OUT_MOD=3'b101;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
@ -772,7 +773,7 @@ always @( posedge clock ) begin
opcode_size=1;
in_alu_sel1=2'b00;
in_alu_sel2=2'b11;
MEM_OR_IO=0;
MEM_OR_IO<=0;
if(Wbit==1)begin
PARAM_ACTION=`LOAD_16;
end else begin
@ -813,16 +814,16 @@ always @( posedge clock ) begin
opcode_size=0;
in_alu_sel1=2'b00;
in_alu_sel2=2'b11;
reg_read_port1_addr={Wbit,3'b000};
reg_read_port1_addr<={Wbit,3'b000};
PARAM_ACTION=`LOAD_8;
HALT <= 0;
PARAM1=0;
PARAM1<=0;
OUT_MOD={3'b000};
DEPENDS_ON_PREVIOUS<=0;
IN_MOD=3'b011;
next_state=`EXEC_WRITE_ENTRY;
`normal_instruction
MEM_OR_IO=1;
MEM_OR_IO<=1;
end
11'b1100_1111_???:begin
/* IRET - Return from interrupt */
@ -832,7 +833,7 @@ always @( posedge clock ) begin
opcode_size=0;
Wbit=1;
Sbit=0;
PARAM1=2;
PARAM1<=2;
seq_addr_entry<=`UCODE_RET_ENTRY;
`normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
@ -847,7 +848,7 @@ always @( posedge clock ) begin
Wbit=INSTRUCTION[24:24];
IN_MOD={1'b0,INSTRUCTION[23:22]};
RM={INSTRUCTION[18:16]};
MEM_OR_IO=0;
MEM_OR_IO<=0;
if(Wbit==1)begin
PARAM_ACTION=`LOAD_16;
end else begin
@ -855,15 +856,15 @@ always @( posedge clock ) begin
end
in_alu_sel1=2'b00; /* PARAM1 */
case(INSTRUCTION[21:19])
3'b100: ALU_OP=`ALU_OP_AND;
3'b001: ALU_OP=`ALU_OP_OR;
3'b100: ALU_OP<=`ALU_OP_AND;
3'b001: ALU_OP<=`ALU_OP_OR;
default:begin end
endcase
case(IN_MOD)
3'b011:begin
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,RM};
reg_write_addr={Wbit,RM};
reg_read_port2_addr<={Wbit,RM};
reg_write_addr<={Wbit,RM};
next_state=`EXEC_WRITE_ENTRY;
end
default:begin
@ -889,11 +890,11 @@ always @( posedge clock ) begin
IN_MOD=3'b011;
RM=INSTRUCTION[18:16];
in_alu_sel1=2'b01;//constantly register
reg_read_port1_addr={Wbit,INSTRUCTION[21:19]};
reg_read_port1_addr<={Wbit,INSTRUCTION[21:19]};
if(IN_MOD==3'b011)begin
in_alu_sel2=2'b01;
reg_read_port2_addr={Wbit,RM};
reg_write_addr={Wbit,RM};
reg_read_port2_addr<={Wbit,RM};
reg_write_addr<={Wbit,RM};
next_state=`EXEC_WRITE_ENTRY;
end else begin
in_alu_sel2=2'b00;
@ -903,12 +904,12 @@ always @( posedge clock ) begin
PARAM_ACTION=`LOAD_8;
end
end
MEM_OR_IO=0;
MEM_OR_IO<=0;
memio_address_select=0;
case (INSTRUCTION[29:26])
4'b0000: ALU_OP=`ALU_OP_ADD;
4'b1010: ALU_OP=`ALU_OP_SUB;
4'b1110: ALU_OP=`ALU_OP_SUB_REVERSE;
4'b0000: ALU_OP<=`ALU_OP_ADD;
4'b1010: ALU_OP<=`ALU_OP_SUB;
4'b1110: ALU_OP<=`ALU_OP_SUB_REVERSE;
default: begin end
endcase
case (INSTRUCTION[29:26])
@ -943,32 +944,32 @@ always @( posedge clock ) begin
default: begin end /*impossible*/
endcase
if(ucode_data[36:36]==0) /*Set reg write address*/
reg_write_addr = ucode_data[12:9 ];
reg_write_addr <= ucode_data[12:9 ];
in_alu_sel1 = ucode_data[14:13];
in_alu_sel2 = ucode_data[16:15];
OUT_MOD = ucode_data[19:17];
/*1:1 map essentially but I want to keep the spec for these bits separate
* from the alu op select bits*/
case(ucode_data[22:20])
3'b000: ALU_OP=`ALU_OP_ADD;
3'b001: ALU_OP=`ALU_OP_SUB;
3'b010: ALU_OP=`ALU_OP_AND;
3'b011: ALU_OP=`ALU_OP_OR;
3'b100: ALU_OP=`ALU_OP_XOR;
3'b101: ALU_OP=`ALU_OP_ADD_SIGNED_B;
3'b110: ALU_OP=`ALU_OP_SUB_REVERSE;
3'b111: ALU_OP=`ALU_OP_SHIFT_LEFT;
3'b000: ALU_OP<=`ALU_OP_ADD;
3'b001: ALU_OP<=`ALU_OP_SUB;
3'b010: ALU_OP<=`ALU_OP_AND;
3'b011: ALU_OP<=`ALU_OP_OR;
3'b100: ALU_OP<=`ALU_OP_XOR;
3'b101: ALU_OP<=`ALU_OP_ADD_SIGNED_B;
3'b110: ALU_OP<=`ALU_OP_SUB_REVERSE;
3'b111: ALU_OP<=`ALU_OP_SHIFT_LEFT;
default: begin end
endcase
if(ucode_data[34:34]==0) /* Set reg read port 1 address */
reg_read_port1_addr=ucode_data[26:23];
reg_read_port1_addr<=ucode_data[26:23];
IN_MOD=ucode_data[29:27];
if(ucode_data[35:35]==0) /* Set reg read port 1 address */
reg_read_port2_addr=ucode_data[33:30];
reg_read_port2_addr<=ucode_data[33:30];
if(ucode_data[37:37]==1) /* Overwrite Wbit */
Wbit=ucode_data[38:38];
memio_address_select=ucode_data[39:39];
MEM_OR_IO=0;
MEM_OR_IO<=0;
HALT <= 0;
ERROR <= 0; //TODO probably, right?
end
@ -977,18 +978,18 @@ always @( posedge clock ) begin
if(opcode_size==0)begin
if({Sbit,Wbit}==2'b11)begin
/*signed "16bit" read*/
PARAM1 = {{8{INSTRUCTION[23:23]}},INSTRUCTION[23:16]};
PARAM1 <= {{8{INSTRUCTION[23:23]}},INSTRUCTION[23:16]};
end else begin
//PARAM1[7:0] = INSTRUCTION[23:16];
PARAM1 = {8'b0,INSTRUCTION[23:16]};
PARAM1 <= {8'b0,INSTRUCTION[23:16]};
end
end else begin
if({Sbit,Wbit}==2'b11)begin
/*signed "16bit" read*/
PARAM1 = {{8{INSTRUCTION[15:15]}},INSTRUCTION[15:8]};
PARAM1 <= {{8{INSTRUCTION[15:15]}},INSTRUCTION[15:8]};
end else begin
//PARAM1[7:0] = INSTRUCTION[15:8];
PARAM1 = {8'b0,INSTRUCTION[15:8]};
PARAM1 <= {8'b0,INSTRUCTION[15:8]};
end
end
case(IN_MOD)
@ -997,11 +998,11 @@ always @( posedge clock ) begin
endcase
end else if (PARAM_ACTION == `LOAD_16) begin
if(opcode_size==0)begin
PARAM1[7:0] = INSTRUCTION[23:16];
PARAM1[15:8] = INSTRUCTION[15:8];
PARAM1[7:0] <= INSTRUCTION[23:16];
PARAM1[15:8] <= INSTRUCTION[15:8];
end else begin
PARAM1[15:8] = INSTRUCTION[7:0];
PARAM1[7:0] = INSTRUCTION[15:8];
PARAM1[15:8] <= INSTRUCTION[7:0];
PARAM1[7:0] <= INSTRUCTION[15:8];
end
case(IN_MOD)
3'b000,3'b001,3'b010: next_state = `EXEC_MEMIO_READ;
@ -1018,7 +1019,7 @@ endmodule
/* IN: {INSTRUCTION[31:24],INSTRUCTION[21:19]} */
/* OUT: number in bytes */
module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT );
always @( IN ) begin
always @* 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 */
@ -1056,7 +1057,7 @@ endmodule
`ifdef INCLUDE_EARLY_CALC_CIRUIT
module Is1 ( input [7:0] IN, output reg VERDICT );
always @( IN ) begin
always @* begin
casez(IN)
8'b0100_???? : VERDICT = 1; /* DEC - Decrement Register | INC - Increment Register */
8'b1111_0100 : VERDICT = 1; /* HLT - Halt */