|
|
|
|
`default_nettype none
|
|
|
|
|
|
|
|
|
|
module decoder (clk, rst, instr, address_code, decoded);
|
|
|
|
|
|
|
|
|
|
`include "parameters.vh"
|
|
|
|
|
|
|
|
|
|
input wire clk;
|
|
|
|
|
input wire rst;
|
|
|
|
|
input wire [7:0] instr;
|
|
|
|
|
output logic [4:0] address_code;
|
|
|
|
|
output logic [7:0] decoded;
|
|
|
|
|
|
|
|
|
|
logic [2:0] row;
|
|
|
|
|
logic [2:0] column;
|
|
|
|
|
logic [1:0] sector;
|
|
|
|
|
|
|
|
|
|
initial address_code = 0;
|
|
|
|
|
always_comb
|
|
|
|
|
begin
|
|
|
|
|
row = instr[7:5];
|
|
|
|
|
column = instr[4:2];
|
|
|
|
|
sector = instr[1:0];
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wire sec_2_stp = (sector == 2) && ((column == 0 && row <= 3) || (column == 4));
|
|
|
|
|
wire sec_2_nop = (sector == 2) && ((column == 0 && (row == 4 || row == 6 || row == 7))
|
|
|
|
|
|| (column == 6 && (row != 4 && row != 5)));
|
|
|
|
|
|
|
|
|
|
always_comb begin
|
|
|
|
|
address_code = 5'h1f;
|
|
|
|
|
decoded = 8'hff;
|
|
|
|
|
if (!rst) begin
|
|
|
|
|
if (sector == 1) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_ORA;
|
|
|
|
|
1: decoded = I_AND;
|
|
|
|
|
2: decoded = I_EOR;
|
|
|
|
|
3: decoded = I_ADC;
|
|
|
|
|
4: decoded = (column == 2 ? I_NOP : I_STA);
|
|
|
|
|
5: decoded = I_LDA;
|
|
|
|
|
6: decoded = I_CMP;
|
|
|
|
|
7: decoded = I_SBC;
|
|
|
|
|
endcase
|
|
|
|
|
|
|
|
|
|
address_code = column;
|
|
|
|
|
end
|
|
|
|
|
else if (sector == 2) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : I_ASL));
|
|
|
|
|
1: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : I_ROL));
|
|
|
|
|
2: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : I_LSR));
|
|
|
|
|
3: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : I_ROR));
|
|
|
|
|
4: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : (column[0] ? I_STX : I_TXA)));
|
|
|
|
|
5: decoded = (sec_2_stp ? I_STP : (column == 2 ? I_TAX : (column == 6 ? I_TSX : I_LDX)));
|
|
|
|
|
6: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : (column == 2 ? I_DEX : I_DEC)));
|
|
|
|
|
7: decoded = (sec_2_stp ? I_STP : ((sec_2_nop || column == 2) ? I_NOP : I_INC));
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
else if (sector == 0) begin
|
|
|
|
|
if (column == 0) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_BRK;
|
|
|
|
|
1: decoded = I_JSR;
|
|
|
|
|
2: decoded = I_RTI;
|
|
|
|
|
3: decoded = I_RTS;
|
|
|
|
|
4: decoded = I_NOP;
|
|
|
|
|
5: decoded = I_LDY;
|
|
|
|
|
6: decoded = I_CPY;
|
|
|
|
|
7: decoded = I_CPX;
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
else if (column == 1) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_NOP;
|
|
|
|
|
1: decoded = I_BIT;
|
|
|
|
|
2: decoded = I_NOP;
|
|
|
|
|
3: decoded = I_NOP;
|
|
|
|
|
4: decoded = I_STY;
|
|
|
|
|
5: decoded = I_LDY;
|
|
|
|
|
6: decoded = I_CPY;
|
|
|
|
|
7: decoded = I_CPX;
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
else if (column == 2) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_PHP;
|
|
|
|
|
1: decoded = I_PLP;
|
|
|
|
|
2: decoded = I_PHA;
|
|
|
|
|
3: decoded = I_PLA;
|
|
|
|
|
4: decoded = I_DEY;
|
|
|
|
|
5: decoded = I_TAY;
|
|
|
|
|
6: decoded = I_INY;
|
|
|
|
|
7: decoded = I_INX;
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
else if (column == 3) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_NOP;
|
|
|
|
|
1: decoded = I_BIT;
|
|
|
|
|
2: decoded = I_JMP;
|
|
|
|
|
3: decoded = I_JMP;
|
|
|
|
|
4: decoded = I_STY;
|
|
|
|
|
5: decoded = I_LDY;
|
|
|
|
|
6: decoded = I_CPY;
|
|
|
|
|
7: decoded = I_CPX;
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
else if (column == 4) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_BPL;
|
|
|
|
|
1: decoded = I_BMI;
|
|
|
|
|
2: decoded = I_BVC;
|
|
|
|
|
3: decoded = I_BVS;
|
|
|
|
|
4: decoded = I_BCC;
|
|
|
|
|
5: decoded = I_BCS;
|
|
|
|
|
6: decoded = I_BNE;
|
|
|
|
|
7: decoded = I_BEQ;
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
else if (column == 5) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_NOP;
|
|
|
|
|
1: decoded = I_NOP;
|
|
|
|
|
2: decoded = I_NOP;
|
|
|
|
|
3: decoded = I_NOP;
|
|
|
|
|
4: decoded = I_STY;
|
|
|
|
|
5: decoded = I_LDY;
|
|
|
|
|
6: decoded = I_NOP;
|
|
|
|
|
7: decoded = I_NOP;
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
else if (column == 6) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_CLC;
|
|
|
|
|
1: decoded = I_SEC;
|
|
|
|
|
2: decoded = I_CLI;
|
|
|
|
|
3: decoded = I_SEI;
|
|
|
|
|
4: decoded = I_TYA;
|
|
|
|
|
5: decoded = I_CLV;
|
|
|
|
|
6: decoded = I_CLD;
|
|
|
|
|
7: decoded = I_SED;
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
else if (column == 7) begin
|
|
|
|
|
case (row)
|
|
|
|
|
0: decoded = I_NOP;
|
|
|
|
|
1: decoded = I_NOP;
|
|
|
|
|
2: decoded = I_NOP;
|
|
|
|
|
3: decoded = I_NOP;
|
|
|
|
|
4: decoded = I_SHY;
|
|
|
|
|
5: decoded = I_LDY;
|
|
|
|
|
6: decoded = I_NOP;
|
|
|
|
|
7: decoded = I_NOP;
|
|
|
|
|
endcase
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if (sector == 0) begin
|
|
|
|
|
if (column == 0) begin
|
|
|
|
|
if (row == 0 || (row >= 2 && row <= 4)) begin
|
|
|
|
|
address_code = ADDR_MODE_IMPLIED;
|
|
|
|
|
end
|
|
|
|
|
else if (row == 1) begin
|
|
|
|
|
address_code = ADDR_MODE_ABSOLUTE;
|
|
|
|
|
end
|
|
|
|
|
else begin
|
|
|
|
|
address_code = ADDR_MODE_IMMEDIATE;
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
else if(column == 1) begin
|
|
|
|
|
address_code = ADDR_MODE_ZP;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 2) begin
|
|
|
|
|
address_code = ADDR_MODE_IMPLIED;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 3) begin
|
|
|
|
|
if (row == 2) begin
|
|
|
|
|
address_code = ADDR_MODE_ABSOLUTE;
|
|
|
|
|
end
|
|
|
|
|
else begin
|
|
|
|
|
address_code = ADDR_MODE_INDEXED_ABSOLUTE;
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
else if (column == 4) begin
|
|
|
|
|
address_code = ADDR_MODE_RELATIVE;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 5) begin
|
|
|
|
|
address_code = ADDR_MODE_INDEXED_ZP;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 6) begin
|
|
|
|
|
address_code = ADDR_MODE_IMPLIED;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 7) begin
|
|
|
|
|
address_code = ADDR_MODE_INDEXED_ABSOLUTE;
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
else if(sector == 1) begin
|
|
|
|
|
if (column == 0) begin
|
|
|
|
|
address_code = ADDR_MODE_PREINDEXED_INDIRECT;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 1) begin
|
|
|
|
|
address_code = ADDR_MODE_ZP;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 2) begin
|
|
|
|
|
address_code = ADDR_MODE_IMMEDIATE;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 3) begin
|
|
|
|
|
address_code = ADDR_MODE_ABSOLUTE;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 4) begin
|
|
|
|
|
address_code = ADDR_MODE_POSTINDEXED_INDIRECT;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 5) begin
|
|
|
|
|
address_code = ADDR_MODE_INDEXED_ZP;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 6 || column == 7) begin
|
|
|
|
|
address_code = ADDR_MODE_INDEXED_ABSOLUTE;
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
else if(sector == 2) begin
|
|
|
|
|
if (column == 0) begin
|
|
|
|
|
address_code = ADDR_MODE_IMMEDIATE;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 1) begin
|
|
|
|
|
address_code = ADDR_MODE_ZP;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 2 || column == 6) begin
|
|
|
|
|
address_code = ADDR_MODE_IMPLIED;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 3) begin
|
|
|
|
|
address_code = ADDR_MODE_ABSOLUTE;
|
|
|
|
|
end
|
|
|
|
|
// column == 4 are invalid opcodes
|
|
|
|
|
else if (column == 5) begin
|
|
|
|
|
address_code = ADDR_MODE_INDEXED_ZP;
|
|
|
|
|
end
|
|
|
|
|
else if (column == 7) begin
|
|
|
|
|
address_code = ADDR_MODE_INDEXED_ABSOLUTE;
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
`ifdef FORMAL
|
|
|
|
|
|
|
|
|
|
reg f_past_valid;
|
|
|
|
|
initial f_past_valid = 0;
|
|
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
|
assume(rst == 0);
|
|
|
|
|
|
|
|
|
|
always @(posedge clk)
|
|
|
|
|
f_past_valid <= 1;
|
|
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
|
if (instr == 8'h00) // BRK
|
|
|
|
|
begin
|
|
|
|
|
assert (decoded == I_BRK);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
|
if (instr == 8'h4C) // JMP abs
|
|
|
|
|
begin
|
|
|
|
|
assert (decoded == I_JMP);
|
|
|
|
|
assert (address_code == ADDR_MODE_ABSOLUTE);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
|
if (instr == 8'h8D) // STA abs
|
|
|
|
|
begin
|
|
|
|
|
assert (decoded == I_STA);
|
|
|
|
|
assert (address_code == ADDR_MODE_ABSOLUTE);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
|
if (instr == 8'hA2) // LDX imm
|
|
|
|
|
begin
|
|
|
|
|
assert (decoded == I_LDX);
|
|
|
|
|
assert (address_code == ADDR_MODE_IMMEDIATE);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
|
if (instr == 8'hA9) // LDA imm
|
|
|
|
|
begin
|
|
|
|
|
assert (decoded == I_LDA);
|
|
|
|
|
assert (address_code == ADDR_MODE_IMMEDIATE);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
|
if (instr == 8'hCA) // DEX
|
|
|
|
|
begin
|
|
|
|
|
assert (decoded == I_DEX);
|
|
|
|
|
assert (address_code == ADDR_MODE_IMPLIED);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
|
if (instr == 8'hE0) // CPX
|
|
|
|
|
begin
|
|
|
|
|
assert (decoded == I_CPX);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
`endif
|
|
|
|
|
|
|
|
|
|
endmodule
|