§ Программа на Verilog
Здесь будут коды процессора.Ревизия #5 :: 17 авг 2024 + INC, DEC d
Ревизия #6 :: 20 авг 2024 + ROR d,u; ROR d,i
1/* verilator lint_off WIDTHTRUNC */ 2/* verilator lint_off WIDTHEXPAND */ 3/* verilator lint_off CASEX */ 4/* verilator lint_off CASEINCOMPLETE */ 5 6module core 7( 8 input clock, // Тактовая частота 25 мгц 9 input reset_n, // Сброс процессора 10 input ce, // ChipEnabled 11 output [7:0] address, // Адрес 12 input [7:0] in, // Данные 13 output reg [7:0] wb, // Что писать в память или регистр 14 output reg we, // Запрос записи в память 15 output reg rr // Запрос чтения из памяти 16); 17 18assign address = mm ? cp : pc; 19 20localparam 21 22 ADD = 2'b00, SUB = 2'b01, AND = 2'b10, XOR = 2'b11, 23 TST = 2'b00, ORI = 2'b01; 24 25// Список всех регистров 26// --------------------------------------------------------------------- 27reg [1:0] t; 28reg mm, rw; 29reg [1:0] rn; // Номер регистра для записи 30reg [7:0] opc, pc, cp; // Опкод, Program Counter, Current Pointer 31reg [7:0] a = 8'h71, 32 b = 8'h23, 33 x = 8'h52, 34 y = 8'hAF; 35reg zf = 1'b0, // Флаг нуля 36 cf = 1'b0; // Флаг переноса 37 38// Предвычисления 39// --------------------------------------------------------------------- 40wire [7:0] opcode = t ? opc : in; 41wire [7:0] pcn = pc + 1; 42 43// Именование проводов 44wire [1:0] dst = opcode[1:0], 45 src = opcode[3:2], 46 o54 = opcode[5:4]; 47wire o0 = opcode[0], o1 = opcode[1], o2 = opcode[2], 48 o3 = opcode[3], o4 = opcode[4], o5 = opcode[5], 49 o7 = opcode[7]; 50 51// Регистр слева 52wire [7:0] rd = dst == 2'b00 ? a : dst == 2'b01 ? b : dst == 2'b10 ? x : y; 53wire [7:0] rs = src == 2'b00 ? a : src == 2'b01 ? b : src == 2'b10 ? x : y; 54wire [8:0] alu = o54 == ADD ? (rd + rs) : o54 == SUB ? (rd - rs) : o54 == AND ? (rd & rs) : (rd ^ rs); 55wire [8:0] asb = src == ADD ? (rd + in) : rd - in; 56wire [7:0] lgc = src == ORI ? (rd | in) : src == XOR ? (rd ^ in) : (rd & in); 57wire [8:0] inc = o2 ? rd - 1 : rd + 1; 58 59// ROR d,s :: ROR d,u 60wire [16:0] ror = {rd, rd, rd[0]} >> (o7 ? in[2:0] : rs[2:0]); 61// --------------------------------------------------------------------- 62 63always @(posedge clock) 64if (reset_n == 1'b0) begin 65 66 t <= 0; 67 pc <= 0; 68 mm <= 0; 69 rw <= 0; 70 rr <= 0; 71 72end 73// Исполнение опкодов 74else if (ce) begin 75 76 we <= 0; 77 rw <= 0; 78 rr <= 0; 79 rn <= dst; 80 81 // Сохранить опкод 82 if (t == 0) opc <= in; 83 84 casex (opcode) 85 86 // 1T 00 MOV d, s 87 // 2T 01 MOV d, [s] 88 // 3T 10 MOV [d], s 89 // 3T 11 MOV [d], [s] 90 8'b00xx_xxxx: case (t) 91 92 0: begin 93 94 t <= |o54; // Если есть обращение к памяти 95 mm <= |o54; // То установить указатель 96 rw <= o54 == 0; // Если нет памяти, то регистр S => D 97 rr <= o4; // Запрос чтения из памяти 98 cp <= rs; // Указатель на чтение из памяти 99 wb <= rs; // Либо запись в регистр, если RW=1 100 pc <= pcn; 101 102 end 103 104 1: begin 105 106 t <= o5 ? 2 : 0; // Запись и убрать MM 107 wb <= o4 ? in : rs; // Что писать 108 mm <= o5; // Убрать mm, если в регистр 109 we <= o5; // Либо в память 110 rw <= !o5; // Запись в регистр 111 cp <= rd; // И куда писать в память 112 113 end 114 115 2: begin t <= 0; mm <= 0; end 116 117 endcase 118 119 // 2T 00 MOV d,u 120 // 3T 01 MOV d,[u] 121 // 4T 10 MOV [d],u 122 // 4T 11 MOV [d],[u] 123 8'b0100_xxxx: case (t) 124 125 0: begin t <= o2 ? 1 : 2; pc <= pcn; end 126 1: begin t <= 2; mm <= 1; cp <= in; rr <= 1; end 127 2: begin 128 129 t <= src ? 3 : 0; // Выбрана память 130 rw <= !o3; // Запись в регистр 131 mm <= o3; // Выбрать cp, если есть запись 132 we <= o3; // Или запись в память 133 wb <= in; // Что писать 134 cp <= rd; // Запись в [d] 135 pc <= pcn; 136 137 end 138 139 3: begin t <= 0; mm <= 0; end 140 141 endcase 142 143 // 3T 0 MOV [u],d 144 // 4T 1 MOV [u],[d] 145 8'b0101_1xxx: case (t) 146 147 0: begin t <= o2 ? 1 : 2; pc <= pcn; end 148 1: begin t <= 2; mm <= 1; cp <= rd; wb <= in; rr <= 1; end 149 2: begin 150 151 t <= 3; 152 mm <= 1; 153 we <= 1; 154 wb <= o2 ? in : rd; // [d] или d 155 cp <= o2 ? wb : in; // [u] 156 pc <= pcn; 157 158 end 159 3: begin t <= 0; mm <= 0; end 160 161 endcase 162 163 // 2T ADD d, u 164 // 2T CMP d, u 165 8'b0101_0xxx: case (t) 166 167 0: begin t <= 1; pc <= pcn; end 168 1: begin t <= 0; pc <= pcn; rw <= !o2; wb <= asb; {cf, zf} <= {asb[8], asb[7:0] == 0}; end 169 170 endcase 171 172 // 1T ROR d, s 173 8'b0110_xxxx: begin 174 175 rw <= 1; // Запись в регистр 176 pc <= pcn; 177 wb <= ror[8:1]; // Результат сдвига 178 zf <= ror[8:1] == 0; // Если 0 179 cf <= ror[0]; // Есть перенос 180 181 end 182 183 // 2T TST, ORI, AND, XOR d, u 184 8'b0111_xxxx: case (t) 185 186 0: begin t <= 1; pc <= pcn; end 187 1: begin 188 189 t <= 0; 190 pc <= pcn; 191 rw <= |src; // Пишется все, кроме TST 192 wb <= lgc; 193 zf <= lgc == 0; 194 cf <= lgc[7]; // Копировать знак => CF 195 196 end 197 198 endcase 199 200 // 1T ADD, SUB, AND, XOR 201 8'b10xx_xxxx: begin 202 203 rw <= 1; 204 pc <= pcn; 205 wb <= alu; // Записать результат в регистр 206 cf <= alu[o5 ? 7 : 8]; // Логические копируют 7й бит 207 zf <= alu[7:0] == 0; // Всем проставлять ZF 208 209 end 210 211 // 2T Jcc u 212 // 2T JMP u 213 // 2T JMP d, u 214 8'b1100_00xx, 215 8'b1100_1000, 216 8'b1100_11xx: case (t) 217 218 0: begin t <= 1; pc <= pcn; end 219 1: begin 220 221 t <= 0; 222 pc <= ((o1 ? zf : cf) == o0) || o3 ? in : pcn; 223 rw <= &src; 224 wb <= pcn; 225 226 end 227 228 endcase 229 230 // 1T JMP d 231 8'b1100_01xx: begin pc <= rd; end 232 233 // CLC, CMC 234 8'b1100_1010: begin cf <= cf & 0; end 235 8'b1100_1011: begin cf <= cf ^ 1; end 236 237 // 1T INC|DEC d 238 8'b1101_0xxx: begin 239 240 pc <= pcn; 241 rw <= 1; 242 wb <= inc[7:0]; 243 cf <= inc[8]; 244 zf <= inc[7:0] == 0; 245 246 end 247 248 // 2T ROR d,u 249 // 3T ROR d,[u] 250 8'b1101_10xx: case (t) 251 252 0: begin t <= o2 ? 1 : 2; pc <= pcn; end 253 1: begin t <= 2; mm <= 1; cp <= in; end 254 2: begin 255 256 t <= 0; 257 rw <= 1; 258 pc <= pcn; 259 wb <= ror[8:1]; 260 zf <= ror[8:1] == 0; 261 cf <= ror[0]; 262 263 end 264 265 endcase 266 267 endcase 268 269end 270 271// Запись в регистры 272always @(negedge clock) 273begin 274 275 if (rw) 276 case (rn) 277 2'b00: a <= wb; 2'b01: b <= wb; 278 2'b10: x <= wb; 2'b11: y <= wb; 279 endcase 280 281end 282 283endmodule