From 064b1c07272676a5766682fd0938655f36042932 Mon Sep 17 00:00:00 2001 From: Denis Tereshkin Date: Sat, 2 Dec 2023 11:25:32 +0700 Subject: [PATCH] Add decoder --- src/alu.verilog | 39 +++++----- src/decoder.verilog | 171 ++++++++++++++++++++++++++++++++++++++++++++ src/parameters.vh | 90 +++++++++++++++++++++++ 3 files changed, 278 insertions(+), 22 deletions(-) create mode 100644 src/decoder.verilog create mode 100644 src/parameters.vh diff --git a/src/alu.verilog b/src/alu.verilog index 9d69433..88f3afd 100644 --- a/src/alu.verilog +++ b/src/alu.verilog @@ -1,40 +1,35 @@ module alu ( - input nrst, - input clk, - input [7:0] A, - input [7:0] B, - input C, - input [2:0] sel, + input nrst, + input clk, + input [7:0] A, + input [7:0] B, + input C, + input [2:0] sel, output [7:0] result, - output r_n, - output r_z, - output reg r_v, - output reg r_c + output r_n, + output r_z, + output reg r_v, + output reg r_c ); - localparam OP_OR = 0; - localparam OP_AND = 1; - localparam OP_EOR = 2; - localparam OP_ADC = 3; - localparam OP_SUB = 4; - localparam OP_ROT = 5; - localparam OP_SHF = 6; - - localparam SHIFT_LEFT = 0; - localparam SHIFT_RIGHT = 1; - wire rst = !nrst; reg [8:0] buffer; wire [8:0] sum; wire [8:0] diff; - + assign result[7:0] = buffer[7:0]; assign r_z = buffer[7:0] == 0; assign r_n = buffer[7]; assign sum = A + B + C; assign diff = A - B - (1 - C); + initial begin + buffer <= 0; + r_v <= 0; + r_c <= 0; + end + always @(posedge clk) begin case (sel) diff --git a/src/decoder.verilog b/src/decoder.verilog new file mode 100644 index 0000000..ad1223b --- /dev/null +++ b/src/decoder.verilog @@ -0,0 +1,171 @@ + +module decoder + ( + input clk, + input rst, + input [7:0] instr, + output reg [3:0] address_code, + output reg [7:0] decoded + ); + +`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 @* begin + if (rst) begin + address_code <= 0; + 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; + 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 + if (column > 0) begin + address_code <= column + end + else begin + address_code <= ADDR_MODE_IMMEDIATE; + 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; + 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 + + if (column > 0) begin + address_code <= column; + end + else begin + if (row >= 4) begin + address_code <= ADDR_MODE_IMMEDIATE; + end + else begin + address_code <= ADDR_MODE_ABSOLUTE; + end + end + end + end +end + +endmodule diff --git a/src/parameters.vh b/src/parameters.vh new file mode 100644 index 0000000..9ac7abe --- /dev/null +++ b/src/parameters.vh @@ -0,0 +1,90 @@ + +parameter ADDR_MODE_INDEXED_INDIRECT = 0; +parameter ADDR_MODE_ZP = 1; +parameter ADDR_MODE_IMMEDIATE = 2; +parameter ADDR_MODE_ABSOLUTE = 3; +parameter ADDR_MODE_INDIRECT_INDEXED = 4; +parameter ADDR_MODE_ZP_X = 5; +parameter ADDR_MODE_ABS_Y = 6; +parameter ADDR_MODE_ABS_X = 7; + +parameter OP_OR = 0; +parameter OP_AND = 1; +parameter OP_EOR = 2; +parameter OP_ADC = 3; +parameter OP_SUB = 4; +parameter OP_ROT = 5; +parameter OP_SHF = 6; + +parameter SHIFT_LEFT = 0; +parameter SHIFT_RIGHT = 1; + +parameter I_LDA = 0; +parameter I_LDX = 1; +parameter I_LDY = 2; +parameter I_STA = 3; +parameter I_STX = 4; +parameter I_STY = 5; +parameter I_TAX = 6; +parameter I_TAY = 7; +parameter I_TXA = 8; +parameter I_TYA = 9; +parameter I_TSX = 10; +parameter I_TXS = 11; +parameter I_PHA = 12; +parameter I_PHP = 13; +parameter I_PLA = 14; +parameter I_PLP = 15; +parameter I_AND = 16; +parameter I_EOR = 17; +parameter I_ORA = 18; +parameter I_BIT = 19; +parameter I_ADC = 20; +parameter I_SBC = 21; +parameter I_CMP = 22; +parameter I_CPX = 23; +parameter I_CPY = 24; +parameter I_INC = 25; +parameter I_INX = 26; +parameter I_INY = 27; +parameter I_DEC = 28; +parameter I_DEX = 29; +parameter I_DEY = 30; +parameter I_ASL = 31; +parameter I_LSR = 32; +parameter I_ROL = 33; +parameter I_ROR = 34; +parameter I_JMP = 35; +parameter I_JSR = 36; +parameter I_RTS = 37; +parameter I_BCC = 38; +parameter I_BCS = 39; +parameter I_BEQ = 40; +parameter I_BMI = 41; +parameter I_BNE = 42; +parameter I_BPL = 43; +parameter I_BVC = 44; +parameter I_BVS = 45; +parameter I_CLC = 46; +parameter I_CLD = 47; +parameter I_CLI = 48; +parameter I_CLV = 49; +parameter I_SEC = 50; +parameter I_SED = 51; +parameter I_SEI = 52; +parameter I_BRK = 53; +parameter I_NOP = 54; +parameter I_RTI = 55; + +// Unofficial opcodes +parameter I_STP = 56; +parameter I_SHY = 57; + + +parameter P_N = 8'h80; +parameter P_V = 8'h40; +parameter P_B = 8'h10; +parameter P_D = 8'h08; +parameter P_I = 8'h04; +parameter P_Z = 8'h02; +parameter P_C = 8'h01;