6 `define BIT_LOAD_INSTR 4
14 `define BIT_FLAGS_WR 12
15 `define BIT_TIMER_RST 14
22 `define MEM_EN (16'b1 << `BIT_MEM_EN)
23 `define PC_INC (16'b1 << `BIT_PC_INC)
24 `define ACC_WR (16'b1 << `BIT_ACC_WR)
25 `define ACC_EN (16'b1 << `BIT_ACC_EN)
26 `define MAR_WR (16'b1 << `BIT_MAR_WR)
27 `define LOAD_INSTR (16'b1 << `BIT_LOAD_INSTR)
28 `define REG_WR (16'b1 << `BIT_REG_WR)
29 `define ALU_EN (16'b1 << `BIT_ALU_EN)
30 `define PC_EN (16'b1 << `BIT_PC_EN)
31 `define MAR_EN (16'b1 << `BIT_MAR_EN)
32 `define MEM_WR (16'b1 << `BIT_MEM_WR)
33 `define PC_WR (16'b1 << `BIT_PC_WR)
34 `define FLAGS_WR (16'b1 << `BIT_FLAGS_WR)
35 `define TIMER_RST (16'b1 << `BIT_TIMER_RST)
36 `define HLT (16'b1 << `BIT_HLT)
38 `define ZERO (4'b1 << `BIT_ZERO)
39 `define CARRY (4'b1 << `BIT_CARRY)
41 module ProgramCounter(
52 always@ (posedge clk or posedge rst)
62 assign addr = en && !wr ? value : 12'hzzz;
64 endmodule // ProgramCounter
67 output reg [7:0] data_out = 0,
74 always@ (posedge clk or posedge rst)
96 always@ (posedge clk or posedge rst)
105 assign bus = (!wr && en) ? value : 8'hzz;
106 endmodule // Accumulator
108 module InstructionDecoder(
112 output reg [`BIT_HLT:0] control_word
114 wire [`BIT_HLT:0] cw_instr [15:0] [15:2];
117 assign cw_instr[4'b0000][4'b0010] = `HLT;
120 assign cw_instr[4'b0001][4'b0010] = `PC_EN | `MEM_EN | `ACC_WR;
121 assign cw_instr[4'b0001][4'b0011] = `PC_INC | `TIMER_RST;
124 assign cw_instr[4'b0010][4'b0010] = `PC_EN | `MEM_EN | `REG_WR;
125 assign cw_instr[4'b0010][4'b0011] = `PC_INC | `ALU_EN | `ACC_WR | `TIMER_RST;
128 assign cw_instr[4'b0011][4'b0010] = `PC_EN | `MEM_EN | `MAR_WR;
129 assign cw_instr[4'b0011][4'b0011] = `PC_INC | `MAR_EN | `MEM_EN | `ACC_WR | `TIMER_RST;
132 assign cw_instr[4'b0100][4'b0010] = `PC_EN | `MEM_EN | `MAR_WR;
133 assign cw_instr[4'b0100][4'b0011] = `PC_INC | `MAR_EN | `MEM_WR | `ACC_EN | `TIMER_RST;
136 assign cw_instr[4'b0101][4'b0010] = `PC_EN | `MEM_EN | `MAR_WR;
137 assign cw_instr[4'b0101][4'b0011] = `MAR_EN | `PC_WR | `TIMER_RST;
139 always@ (negedge clk)
141 4'b0000: control_word <= `PC_EN | `MEM_EN | `LOAD_INSTR;
142 4'b0001: control_word <= `PC_INC;
143 default: control_word <= cw_instr[instr[7:4]][timer];
146 endmodule // InstructionDecoder
152 input [3:0] flags_in,
154 output [3:0] flags_out,
162 4'b0000: result = in_a + in_b;
163 4'b0001: result = in_a - in_b;
164 4'b0010: result = { 1'b0, in_a & in_b };
165 4'b0011: result = { 1'b0, in_a | in_b };
166 4'b0100: result = { 1'b0, in_a ^ in_b };
167 4'b0101: result = { 1'b0, in_a << in_b };
168 4'b0110: result = { 1'b0, in_a >> in_b };
169 4'b0111: result = { 1'b0, in_a >>> in_b };
170 default: result = 9'bx;
174 assign flags_out[`BIT_ZERO] = result[7:0] == 0;
175 assign flags_out[`BIT_CARRY] = result[8];
176 assign out = en ? result[7:0] : 8'bz;
180 output [11:0] addr_out,
189 wire [`BIT_HLT:0] control_word;
193 wire [3:0] flags_alu;
198 assign debug = instr;
202 .inc(control_word[`BIT_PC_INC]),
203 .en(control_word[`BIT_PC_EN]),
204 .wr(control_word[`BIT_PC_WR]),
212 .wr(control_word[`BIT_LOAD_INSTR]),
217 InstructionDecoder _idec(
221 .control_word(control_word)
229 .wr(control_word[`BIT_ACC_WR]),
230 .en(control_word[`BIT_ACC_EN])
238 .wr(control_word[`BIT_REG_WR])
247 .flags_out(flags_alu),
248 .en(control_word[`BIT_ALU_EN])
251 assign addr_out = control_word[`BIT_MAR_EN] ? mar : 12'hzzz;
252 assign mem_wr = control_word[`BIT_MEM_WR];
253 assign mem_en = control_word[`BIT_MEM_EN];
255 always@ (posedge clk or posedge rst)
258 else if (control_word[`BIT_FLAGS_WR])
261 always@ (posedge clk or posedge rst)
264 else if (control_word[`BIT_HLT])
267 always@ (posedge clk)
268 if (control_word[`BIT_MAR_WR])
269 mar <= { instr[3:0], bus };
271 always@ (posedge clk or posedge rst)
274 else if (control_word[`BIT_TIMER_RST])