§ Ядро процессора

Процессор, основанный на анализе и повторе js-эмулятора Gigatron.
1module gigatron
2(
3    input   wire        clock,
4    input   wire        rst_n,
5    output  reg  [15:0] pc,
6    input   wire [15:0] rom_i,
7
8    // Чтение и запись
9    output  reg  [15:0] addr_r,
10    output  reg  [15:0] addr_w,
11    input   wire [ 7:0] data_i,
12    output  reg  [ 7:0] data_o,
13    output  reg         we,
14
15    // Порты ввода-вывода
16    input   wire [ 7:0] inreg,
17    output  reg  [ 7:0] out,
18    output  reg  [ 7:0] outx,
19
20    // 76543210
21    // ^^^^^^^^
22    // |||||||`-- SCLK
23    // ||||||`--- Not connected
24    // |||||`---- /SS0
25    // ||||`----- /SS1
26    // |||`------ /SS2
27    // ||`------- /SS3
28    // |`-------- B0
29    // `--------- B1 (Memory Bank)
30    output  reg  [ 7:0] ctrl
31);
32
33// Регистры
34reg  [ 7:0] ac  = 0;
35reg  [ 7:0] x   = 0;
36reg  [ 7:0] y   = 0;
37reg  [15:0] ir  = 16'h0200; /* NOP: LD AC, AC */
38
39initial begin
40
41    pc      = 0;
42    we      = 0;
43    addr_r  = 0;
44    addr_w  = 0;
45    data_o  = 0;
46    out     = 0;
47    outx    = 0;
48    ctrl    = 0;
49
50end
51
52// Декодирование IR
53// ---------------------------------------------------------------------
54wire [ 2:0] op      = ir[15:13]; // 3
55wire [ 2:0] mode    = ir[12:10]; // 3
56wire [ 1:0] bus     = ir[ 9:8];  // 2
57wire [ 7:0] d       = ir[ 7:0];  // 8
58wire [ 7:0] zac     = {~ac[7], ac[6:0]};
59wire [15:0] pcinc   = pc + 1;
60
61// Вычисления
62// ---------------------------------------------------------------------
63reg  [ 7:0] b;
64reg  [ 7:0] alu;
65reg  [ 7:0] base;
66reg         cond;
67
68// Комбинационная логика
69// ---------------------------------------------------------------------
70always @* begin
71
72    base = pc[15:8];
73
74    // Режим ZeroPage для branchOp
75    if (op == 7) addr_r = d;
76    else case (mode)
77
78        0, 4, 5, 6:
79              addr_r = d;
80        1:    addr_r = x;
81        2:    addr_r = {y, d};
82        3, 7: addr_r = {y, x}; // bus=1, mode=7 => X++
83
84    endcase
85
86    // Выборка шины
87    case (bus)
88
89        /* IMM */ 2'b00: b = d;
90        /* MEM */ 2'b01: b = data_i;
91        /* ACC */ 2'b10: b = ac;
92        /* INP */ 2'b11: b = inreg;
93
94    endcase
95
96    // Результат вычисления АЛУ
97    case (op)
98
99        /* AND  */ 1: alu = ac & b;
100        /* OR   */ 2: alu = ac | b;
101        /* EOR  */ 3: alu = ac ^ b;
102        /* ADD  */ 4: alu = ac + b;
103        /* SUB  */ 5: alu = ac - b;
104        /* LOAD */ default: alu = b;
105
106    endcase
107
108    // Вычисление условия
109    case (mode)
110
111        /* JMP */ 0: begin cond = 1; base = y; end
112        /* BGT */ 1: begin cond = zac  > 8'h80; end
113        /* BLT */ 2: begin cond = zac  < 8'h80; end
114        /* BNE */ 3: begin cond = zac != 8'h80; end
115        /* BEQ */ 4: begin cond = zac == 8'h80; end
116        /* BGE */ 5: begin cond = zac >= 8'h80; end
117        /* BLE */ 6: begin cond = zac <= 8'h80; end
118        /* BRA */ 7: begin cond = 1; end
119
120    endcase
121
122end
123
124// Основная логика
125// ---------------------------------------------------------------------
126always @(posedge clock) begin
127
128    ir <= rom_i;
129    pc <= pcinc;
130    we <= 0;
131
132    case (op)
133
134        // storeOp
135        6: begin
136
137            addr_w <= addr_r;
138            data_o <= b;
139            we     <= (bus != 1);
140
141            case (mode)
142
143                4: x <= b;
144                5: y <= b;
145                7: x <= x + 1;
146
147            endcase
148
149            // Дополнительные конфигурации
150            if (bus == 1) ctrl <= d;
151
152        end
153
154        // branchOp
155        7: begin if (cond) pc <= {base, b}; end
156
157        // aluOp (0-5)
158        default: case (mode)
159
160            0, 1, 2, 3: ac <= alu;
161            4: x <= alu;
162            5: y <= alu;
163            6, 7:
164            begin
165
166                // Инкремент X при особых условиях
167                if (mode == 7 && bus == 1) x <= x + 1;
168
169                // Запись содержимого AC в OUTX @(posedge VGA_HS)
170                if (!out[6] && alu[6]) outx <= ac;
171
172                // Запись в порт значения АЛУ
173                out <= alu;
174
175            end
176
177        endcase
178
179    endcase
180
181end
182
183endmodule