Blame


1 8515162d 2024-02-02 benni // Control Word
2 8515162d 2024-02-02 benni `define BIT_MEM_EN 0
3 8515162d 2024-02-02 benni `define BIT_PC_INC 1
4 8515162d 2024-02-02 benni `define BIT_ACC_WR 2
5 8515162d 2024-02-02 benni `define BIT_ACC_EN 3
6 8515162d 2024-02-02 benni `define BIT_LOAD_INSTR 4
7 8515162d 2024-02-02 benni `define BIT_MAR_WR 5
8 8515162d 2024-02-02 benni `define BIT_REG_WR 6
9 8515162d 2024-02-02 benni `define BIT_ALU_EN 7
10 8515162d 2024-02-02 benni `define BIT_PC_EN 8
11 8515162d 2024-02-02 benni `define BIT_MAR_EN 9
12 8515162d 2024-02-02 benni `define BIT_MEM_WR 10
13 8515162d 2024-02-02 benni `define BIT_PC_WR 11
14 8515162d 2024-02-02 benni `define BIT_FLAGS_WR 12
15 8515162d 2024-02-02 benni `define BIT_TIMER_RST 14
16 8515162d 2024-02-02 benni `define BIT_HLT 15
17 8515162d 2024-02-02 benni
18 8515162d 2024-02-02 benni // Flags
19 8515162d 2024-02-02 benni `define BIT_ZERO 0
20 8515162d 2024-02-02 benni `define BIT_CARRY 1
21 8515162d 2024-02-02 benni
22 8515162d 2024-02-02 benni `define MEM_EN (16'b1 << `BIT_MEM_EN)
23 8515162d 2024-02-02 benni `define PC_INC (16'b1 << `BIT_PC_INC)
24 8515162d 2024-02-02 benni `define ACC_WR (16'b1 << `BIT_ACC_WR)
25 8515162d 2024-02-02 benni `define ACC_EN (16'b1 << `BIT_ACC_EN)
26 8515162d 2024-02-02 benni `define MAR_WR (16'b1 << `BIT_MAR_WR)
27 8515162d 2024-02-02 benni `define LOAD_INSTR (16'b1 << `BIT_LOAD_INSTR)
28 8515162d 2024-02-02 benni `define REG_WR (16'b1 << `BIT_REG_WR)
29 8515162d 2024-02-02 benni `define ALU_EN (16'b1 << `BIT_ALU_EN)
30 8515162d 2024-02-02 benni `define PC_EN (16'b1 << `BIT_PC_EN)
31 8515162d 2024-02-02 benni `define MAR_EN (16'b1 << `BIT_MAR_EN)
32 8515162d 2024-02-02 benni `define MEM_WR (16'b1 << `BIT_MEM_WR)
33 8515162d 2024-02-02 benni `define PC_WR (16'b1 << `BIT_PC_WR)
34 8515162d 2024-02-02 benni `define FLAGS_WR (16'b1 << `BIT_FLAGS_WR)
35 8515162d 2024-02-02 benni `define TIMER_RST (16'b1 << `BIT_TIMER_RST)
36 8515162d 2024-02-02 benni `define HLT (16'b1 << `BIT_HLT)
37 8515162d 2024-02-02 benni
38 8515162d 2024-02-02 benni `define ZERO (4'b1 << `BIT_ZERO)
39 8515162d 2024-02-02 benni `define CARRY (4'b1 << `BIT_CARRY)
40 8515162d 2024-02-02 benni
41 8515162d 2024-02-02 benni module ProgramCounter(
42 8515162d 2024-02-02 benni inout [11:0] addr,
43 8515162d 2024-02-02 benni input inc,
44 8515162d 2024-02-02 benni input en,
45 8515162d 2024-02-02 benni input wr,
46 8515162d 2024-02-02 benni input clk,
47 8515162d 2024-02-02 benni input rst
48 8515162d 2024-02-02 benni );
49 8515162d 2024-02-02 benni
50 8515162d 2024-02-02 benni reg [11:0] value = 0;
51 8515162d 2024-02-02 benni
52 8515162d 2024-02-02 benni always@ (posedge clk or posedge rst)
53 8515162d 2024-02-02 benni begin
54 8515162d 2024-02-02 benni if (rst)
55 8515162d 2024-02-02 benni value <= 0;
56 8515162d 2024-02-02 benni else if (wr && !en)
57 8515162d 2024-02-02 benni value <= addr;
58 8515162d 2024-02-02 benni else if (inc)
59 8515162d 2024-02-02 benni value <= value + 1;
60 8515162d 2024-02-02 benni end
61 8515162d 2024-02-02 benni
62 8515162d 2024-02-02 benni assign addr = en && !wr ? value : 12'hzzz;
63 8515162d 2024-02-02 benni
64 8515162d 2024-02-02 benni endmodule // ProgramCounter
65 8515162d 2024-02-02 benni
66 8515162d 2024-02-02 benni module Register(
67 8515162d 2024-02-02 benni output reg [7:0] data_out = 0,
68 8515162d 2024-02-02 benni input [7:0] data_in,
69 8515162d 2024-02-02 benni input wr,
70 8515162d 2024-02-02 benni input clk,
71 8515162d 2024-02-02 benni input rst
72 8515162d 2024-02-02 benni );
73 8515162d 2024-02-02 benni
74 8515162d 2024-02-02 benni always@ (posedge clk or posedge rst)
75 8515162d 2024-02-02 benni begin
76 8515162d 2024-02-02 benni if (rst)
77 8515162d 2024-02-02 benni data_out <= 0;
78 8515162d 2024-02-02 benni else if (wr)
79 8515162d 2024-02-02 benni data_out <= data_in;
80 8515162d 2024-02-02 benni end
81 8515162d 2024-02-02 benni
82 8515162d 2024-02-02 benni endmodule // Register
83 8515162d 2024-02-02 benni
84 8515162d 2024-02-02 benni module Accumulator(
85 8515162d 2024-02-02 benni inout [7:0] bus,
86 8515162d 2024-02-02 benni output [7:0] out,
87 8515162d 2024-02-02 benni input clk,
88 8515162d 2024-02-02 benni input rst,
89 8515162d 2024-02-02 benni input wr,
90 8515162d 2024-02-02 benni input en
91 8515162d 2024-02-02 benni );
92 8515162d 2024-02-02 benni
93 8515162d 2024-02-02 benni reg [7:0] value = 0;
94 8515162d 2024-02-02 benni
95 8515162d 2024-02-02 benni
96 8515162d 2024-02-02 benni always@ (posedge clk or posedge rst)
97 8515162d 2024-02-02 benni begin
98 8515162d 2024-02-02 benni if (rst)
99 8515162d 2024-02-02 benni value <= 0;
100 8515162d 2024-02-02 benni else if (wr && !en)
101 8515162d 2024-02-02 benni value <= bus;
102 8515162d 2024-02-02 benni end
103 8515162d 2024-02-02 benni
104 8515162d 2024-02-02 benni assign out = value;
105 8515162d 2024-02-02 benni assign bus = (!wr && en) ? value : 8'hzz;
106 8515162d 2024-02-02 benni endmodule // Accumulator
107 8515162d 2024-02-02 benni
108 8515162d 2024-02-02 benni module InstructionDecoder(
109 8515162d 2024-02-02 benni input [3:0] timer,
110 8515162d 2024-02-02 benni input [7:0] instr,
111 8515162d 2024-02-02 benni input clk,
112 8515162d 2024-02-02 benni output reg [`BIT_HLT:0] control_word
113 8515162d 2024-02-02 benni );
114 8515162d 2024-02-02 benni wire [`BIT_HLT:0] cw_instr [15:0] [15:2];
115 8515162d 2024-02-02 benni
116 8515162d 2024-02-02 benni // hlt
117 8515162d 2024-02-02 benni assign cw_instr[4'b0000][4'b0010] = `HLT;
118 8515162d 2024-02-02 benni
119 8515162d 2024-02-02 benni // lda imm8
120 8515162d 2024-02-02 benni assign cw_instr[4'b0001][4'b0010] = `PC_EN | `MEM_EN | `ACC_WR;
121 8515162d 2024-02-02 benni assign cw_instr[4'b0001][4'b0011] = `PC_INC | `TIMER_RST;
122 8515162d 2024-02-02 benni
123 8515162d 2024-02-02 benni // alu imm8
124 8515162d 2024-02-02 benni assign cw_instr[4'b0010][4'b0010] = `PC_EN | `MEM_EN | `REG_WR;
125 8515162d 2024-02-02 benni assign cw_instr[4'b0010][4'b0011] = `PC_INC | `ALU_EN | `ACC_WR | `TIMER_RST;
126 8515162d 2024-02-02 benni
127 8515162d 2024-02-02 benni // rb imm12
128 8515162d 2024-02-02 benni assign cw_instr[4'b0011][4'b0010] = `PC_EN | `MEM_EN | `MAR_WR;
129 8515162d 2024-02-02 benni assign cw_instr[4'b0011][4'b0011] = `PC_INC | `MAR_EN | `MEM_EN | `ACC_WR | `TIMER_RST;
130 8515162d 2024-02-02 benni
131 8515162d 2024-02-02 benni // wb imm12
132 8515162d 2024-02-02 benni assign cw_instr[4'b0100][4'b0010] = `PC_EN | `MEM_EN | `MAR_WR;
133 8515162d 2024-02-02 benni assign cw_instr[4'b0100][4'b0011] = `PC_INC | `MAR_EN | `MEM_WR | `ACC_EN | `TIMER_RST;
134 8515162d 2024-02-02 benni
135 8515162d 2024-02-02 benni // jmp imm12
136 8515162d 2024-02-02 benni assign cw_instr[4'b0101][4'b0010] = `PC_EN | `MEM_EN | `MAR_WR;
137 8515162d 2024-02-02 benni assign cw_instr[4'b0101][4'b0011] = `MAR_EN | `PC_WR | `TIMER_RST;
138 8515162d 2024-02-02 benni
139 8515162d 2024-02-02 benni always@ (negedge clk)
140 8515162d 2024-02-02 benni case (timer)
141 8515162d 2024-02-02 benni 4'b0000: control_word <= `PC_EN | `MEM_EN | `LOAD_INSTR;
142 8515162d 2024-02-02 benni 4'b0001: control_word <= `PC_INC;
143 8515162d 2024-02-02 benni default: control_word <= cw_instr[instr[7:4]][timer];
144 8515162d 2024-02-02 benni endcase
145 8515162d 2024-02-02 benni
146 8515162d 2024-02-02 benni endmodule // InstructionDecoder
147 8515162d 2024-02-02 benni
148 8515162d 2024-02-02 benni module ALU(
149 8515162d 2024-02-02 benni input [7:0] in_a,
150 8515162d 2024-02-02 benni input [7:0] in_b,
151 8515162d 2024-02-02 benni input [3:0] funct,
152 8515162d 2024-02-02 benni input [3:0] flags_in,
153 8515162d 2024-02-02 benni output [7:0] out,
154 8515162d 2024-02-02 benni output [3:0] flags_out,
155 8515162d 2024-02-02 benni input en
156 8515162d 2024-02-02 benni );
157 8515162d 2024-02-02 benni reg [8:0] result;
158 8515162d 2024-02-02 benni
159 8515162d 2024-02-02 benni always@ (*)
160 8515162d 2024-02-02 benni begin
161 8515162d 2024-02-02 benni case (funct)
162 8515162d 2024-02-02 benni 4'b0000: result = in_a + in_b;
163 8515162d 2024-02-02 benni 4'b0001: result = in_a - in_b;
164 8515162d 2024-02-02 benni 4'b0010: result = { 1'b0, in_a & in_b };
165 8515162d 2024-02-02 benni 4'b0011: result = { 1'b0, in_a | in_b };
166 8515162d 2024-02-02 benni 4'b0100: result = { 1'b0, in_a ^ in_b };
167 8515162d 2024-02-02 benni 4'b0101: result = { 1'b0, in_a << in_b };
168 8515162d 2024-02-02 benni 4'b0110: result = { 1'b0, in_a >> in_b };
169 8515162d 2024-02-02 benni 4'b0111: result = { 1'b0, in_a >>> in_b };
170 8515162d 2024-02-02 benni default: result = 9'bx;
171 8515162d 2024-02-02 benni endcase
172 8515162d 2024-02-02 benni end
173 8515162d 2024-02-02 benni
174 8515162d 2024-02-02 benni assign flags_out[`BIT_ZERO] = result[7:0] == 0;
175 8515162d 2024-02-02 benni assign flags_out[`BIT_CARRY] = result[8];
176 8515162d 2024-02-02 benni assign out = en ? result[7:0] : 8'bz;
177 8515162d 2024-02-02 benni endmodule // ALU
178 8515162d 2024-02-02 benni
179 8515162d 2024-02-02 benni module CPU(
180 8515162d 2024-02-02 benni output [11:0] addr_out,
181 8515162d 2024-02-02 benni inout [7:0] bus,
182 8515162d 2024-02-02 benni output [7:0] debug,
183 8515162d 2024-02-02 benni output mem_wr,
184 8515162d 2024-02-02 benni output mem_en,
185 8515162d 2024-02-02 benni output reg hlt = 0,
186 8515162d 2024-02-02 benni input clk,
187 8515162d 2024-02-02 benni input rst
188 8515162d 2024-02-02 benni );
189 8515162d 2024-02-02 benni wire [`BIT_HLT:0] control_word;
190 8515162d 2024-02-02 benni wire [7:0] instr;
191 8515162d 2024-02-02 benni wire [7:0] alu_in_a;
192 8515162d 2024-02-02 benni wire [7:0] alu_in_b;
193 8515162d 2024-02-02 benni wire [3:0] flags_alu;
194 8515162d 2024-02-02 benni reg [3:0] timer = 0;
195 8515162d 2024-02-02 benni reg [11:0] mar;
196 8515162d 2024-02-02 benni reg [3:0] flags;
197 8515162d 2024-02-02 benni
198 8515162d 2024-02-02 benni assign debug = instr;
199 8515162d 2024-02-02 benni
200 8515162d 2024-02-02 benni ProgramCounter _pc(
201 8515162d 2024-02-02 benni .addr(addr_out),
202 8515162d 2024-02-02 benni .inc(control_word[`BIT_PC_INC]),
203 8515162d 2024-02-02 benni .en(control_word[`BIT_PC_EN]),
204 8515162d 2024-02-02 benni .wr(control_word[`BIT_PC_WR]),
205 8515162d 2024-02-02 benni .clk(clk),
206 8515162d 2024-02-02 benni .rst(rst)
207 8515162d 2024-02-02 benni );
208 8515162d 2024-02-02 benni
209 8515162d 2024-02-02 benni Register _ireg(
210 8515162d 2024-02-02 benni .data_in(bus),
211 8515162d 2024-02-02 benni .data_out(instr),
212 8515162d 2024-02-02 benni .wr(control_word[`BIT_LOAD_INSTR]),
213 8515162d 2024-02-02 benni .clk(clk),
214 8515162d 2024-02-02 benni .rst(rst)
215 8515162d 2024-02-02 benni );
216 8515162d 2024-02-02 benni
217 8515162d 2024-02-02 benni InstructionDecoder _idec(
218 8515162d 2024-02-02 benni .instr(instr),
219 8515162d 2024-02-02 benni .clk(clk),
220 8515162d 2024-02-02 benni .timer(timer),
221 8515162d 2024-02-02 benni .control_word(control_word)
222 8515162d 2024-02-02 benni );
223 8515162d 2024-02-02 benni
224 8515162d 2024-02-02 benni Accumulator _acc(
225 8515162d 2024-02-02 benni .bus(bus),
226 8515162d 2024-02-02 benni .out(alu_in_a),
227 8515162d 2024-02-02 benni .clk(clk),
228 8515162d 2024-02-02 benni .rst(rst),
229 8515162d 2024-02-02 benni .wr(control_word[`BIT_ACC_WR]),
230 8515162d 2024-02-02 benni .en(control_word[`BIT_ACC_EN])
231 8515162d 2024-02-02 benni );
232 8515162d 2024-02-02 benni
233 8515162d 2024-02-02 benni Register _reg(
234 8515162d 2024-02-02 benni .data_in(bus),
235 8515162d 2024-02-02 benni .data_out(alu_in_b),
236 8515162d 2024-02-02 benni .clk(clk),
237 8515162d 2024-02-02 benni .rst(rst),
238 8515162d 2024-02-02 benni .wr(control_word[`BIT_REG_WR])
239 8515162d 2024-02-02 benni );
240 8515162d 2024-02-02 benni
241 8515162d 2024-02-02 benni ALU _alu(
242 8515162d 2024-02-02 benni .in_a(alu_in_a),
243 8515162d 2024-02-02 benni .in_b(alu_in_b),
244 8515162d 2024-02-02 benni .funct(instr[3:0]),
245 8515162d 2024-02-02 benni .out(bus),
246 8515162d 2024-02-02 benni .flags_in(flags),
247 8515162d 2024-02-02 benni .flags_out(flags_alu),
248 8515162d 2024-02-02 benni .en(control_word[`BIT_ALU_EN])
249 8515162d 2024-02-02 benni );
250 8515162d 2024-02-02 benni
251 8515162d 2024-02-02 benni assign addr_out = control_word[`BIT_MAR_EN] ? mar : 12'hzzz;
252 8515162d 2024-02-02 benni assign mem_wr = control_word[`BIT_MEM_WR];
253 8515162d 2024-02-02 benni assign mem_en = control_word[`BIT_MEM_EN];
254 8515162d 2024-02-02 benni
255 8515162d 2024-02-02 benni always@ (posedge clk or posedge rst)
256 8515162d 2024-02-02 benni if (rst)
257 8515162d 2024-02-02 benni flags <= 0;
258 8515162d 2024-02-02 benni else if (control_word[`BIT_FLAGS_WR])
259 8515162d 2024-02-02 benni flags <= flags_alu;
260 8515162d 2024-02-02 benni
261 8515162d 2024-02-02 benni always@ (posedge clk or posedge rst)
262 8515162d 2024-02-02 benni if (rst)
263 8515162d 2024-02-02 benni hlt <= 0;
264 8515162d 2024-02-02 benni else if (control_word[`BIT_HLT])
265 8515162d 2024-02-02 benni hlt <= 1;
266 8515162d 2024-02-02 benni
267 8515162d 2024-02-02 benni always@ (posedge clk)
268 8515162d 2024-02-02 benni if (control_word[`BIT_MAR_WR])
269 8515162d 2024-02-02 benni mar <= { instr[3:0], bus };
270 8515162d 2024-02-02 benni
271 8515162d 2024-02-02 benni always@ (posedge clk or posedge rst)
272 8515162d 2024-02-02 benni if (rst)
273 8515162d 2024-02-02 benni timer <= 0;
274 8515162d 2024-02-02 benni else if (control_word[`BIT_TIMER_RST])
275 8515162d 2024-02-02 benni timer <= 0;
276 8515162d 2024-02-02 benni else
277 8515162d 2024-02-02 benni timer <= timer + 1;
278 8515162d 2024-02-02 benni endmodule // CPU