6502 implementation in SystemVerilog
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
8.3 KiB

2 years ago
module decoder
(
input clk,
input rst,
input [7:0] instr,
output logic [4:0] address_code,
output logic [7:0] decoded
2 years ago
);
`include "parameters.vh"
wire [2:0] row = instr[7:5];
wire [2:0] column = instr[4:2];
wire [1:0] sector = instr[1:0];
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 = 0;
decoded = 0;
2 years ago
if (rst) begin
address_code = 8'h0;
2 years ago
end
else 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_STA : I_NOP);
5: decoded = I_LDA;
6: decoded = I_CMP;
7: decoded = I_SBC;
2 years ago
endcase
address_code = column;
2 years ago
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));
2 years ago
endcase
if (column > 0) begin
address_code = column;
end
2 years ago
else begin
address_code = ADDR_MODE_IMMEDIATE;
2 years ago
end
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;
2 years ago
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;
2 years ago
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;
2 years ago
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;
2 years ago
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;
2 years ago
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;
2 years ago
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;
2 years ago
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;
2 years ago
endcase
end
end
2 years ago
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
2 years ago
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 == 3) begin
address_code = ADDR_MODE_ABSOLUTE;
2 years ago
end
else begin
address_code = ADDR_MODE_INDEXED_ABSOLUTE;
2 years ago
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
2 years ago
end
end
end
endmodule