summaryrefslogtreecommitdiff
path: root/hdl/core.sv
diff options
context:
space:
mode:
Diffstat (limited to 'hdl/core.sv')
-rw-r--r--hdl/core.sv231
1 files changed, 231 insertions, 0 deletions
diff --git a/hdl/core.sv b/hdl/core.sv
new file mode 100644
index 0000000..919dac9
--- /dev/null
+++ b/hdl/core.sv
@@ -0,0 +1,231 @@
1`include "util.svh"
2
3module core
4 #( ADDR_BITS = 14
5 , DATA_BITS = 12
6 )
7 ( input bit clk
8 , input bit reset
9 );
10
11bit mem_ready;
12bit mem_valid;
13bit mem_write;
14bit [ADDR_BITS-1:0] mem_address;
15bit [DATA_BITS-1:0] mem_write_data;
16
17bit mem_read_valid;
18bit [DATA_BITS-1:0] mem_read_data;
19
20mem
21 #( .ADDR_BITS(ADDR_BITS)
22 , .DATA_BITS(DATA_BITS)
23 , .INIT_FILE("mem/mem.hex")
24 )
25 memory
26 ( .clk(clk)
27 , .reset(reset)
28
29 , .ready(mem_ready)
30 , .valid(mem_valid)
31 , .address(mem_address)
32 , .write(mem_write)
33 , .write_data(mem_write_data)
34
35 , .read_valid(mem_read_valid)
36 , .read_data(mem_read_data)
37 );
38
39bit rx_ready;
40bit rx_valid;
41bit [7:0] rx_data;
42
43bit tx_ready;
44bit tx_valid;
45bit [7:0] tx_data;
46
47jtag_uart
48 #( .INSTANCE(0)
49 ) uart0
50 ( .clk(clk)
51 , .reset(reset)
52
53 , .rx_ready(rx_ready)
54 , .rx_valid(rx_valid)
55 , .rx_data(rx_data)
56
57 , .tx_ready(tx_ready)
58 , .tx_valid(tx_valid)
59 , .tx_data(tx_data)
60 );
61
62bit [ADDR_BITS-1:0] pc;
63bit [3:0] opcode;
64bit [7:0] operand;
65bit [DATA_BITS-1:0] acc;
66
67bit [ADDR_BITS-1:0] address;
68bit [DATA_BITS-1:0] sign_extended_operand;
69
70enum
71 { FETCH
72 , DECODE
73 , INDIRECT
74 , INDIRECTED
75 , AGEN
76 , MEMORY
77 , HALT
78 } state;
79
80always_ff @(posedge clk) begin
81 if (reset) begin
82 mem_valid = 0;
83 rx_ready = 0;
84 tx_valid = 0;
85 tx_data = 0;
86 pc = 0;
87 acc = 0;
88 state = state.first;
89 end else begin
90 if (`lag(tx_ready)) tx_valid = 0;
91
92 case (state)
93 FETCH: begin
94 mem_valid = 1;
95 mem_address = pc;
96 mem_write = 0;
97 if (`lag(mem_ready)) begin
98 state = DECODE;
99 ++pc;
100 end
101 end
102
103 DECODE: begin
104 mem_valid = 0;
105 mem_write = 0;
106 if (`lag(mem_read_valid)) begin
107 state = FETCH;
108 {opcode, operand} = `lag(mem_read_data);
109 sign_extended_operand = {{(DATA_BITS-8){operand[7]}}, operand};
110 case (opcode)
111 'h0: begin
112 if (operand[0]) acc = 0;
113 if (operand[1]) ++acc;
114 if (operand[2]) --acc;
115 if (operand[6]) state = MEMORY;
116 if (operand[7]) begin
117 rx_ready = 1;
118 state = MEMORY;
119 end
120 if (operand == 0) state = HALT;
121 end
122 'h1: acc = sign_extended_operand;
123 'h2, 'h3: begin
124 address = {7'b0, operand[6:0]};
125 state = operand[7] ? INDIRECT : AGEN;
126 end
127 'h4: if (acc != sign_extended_operand) ++pc;
128 'h5: begin
129 if (operand[7]) begin
130 address = {7'b0, operand[6:0]};
131 state = INDIRECT;
132 end else begin
133 pc = pc + {{(ADDR_BITS-7){operand[6]}}, operand[6:0]};
134 end
135 end
136 'h6: begin
137 mem_write_data = acc % 10 + 'h30;
138 acc = acc / 10;
139 address = {7'b0, operand[6:0]};
140 state = operand[7] ? INDIRECT : AGEN;
141 end
142 endcase
143 end
144 end
145
146 INDIRECT: begin
147 mem_valid = 1;
148 mem_write = 0;
149 mem_address = address;
150 state = `lag(mem_ready) ? INDIRECTED : INDIRECT;
151 end
152
153 INDIRECTED: begin
154 if (`lag(mem_ready)) begin
155 mem_valid = 0;
156 mem_write = 0;
157 end
158 if (`lag(mem_read_valid)) begin
159 address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)};
160 state = AGEN;
161 end
162 end
163
164 AGEN: begin
165 mem_valid = 0;
166 mem_write = 0;
167 state = FETCH;
168 case (opcode)
169 'h2: begin
170 mem_valid = 1;
171 mem_address = address;
172 state = `lag(mem_ready) ? MEMORY : AGEN;
173 end
174 'h3: begin
175 mem_valid = 1;
176 mem_address = address;
177 mem_write = 1;
178 mem_write_data = acc;
179 state = `lag(mem_ready) ? FETCH : AGEN;
180 end
181 'h5: pc = address;
182 'h6: begin
183 mem_valid = 1;
184 mem_address = address;
185 mem_write = 1;
186 state = `lag(mem_ready) ? FETCH : AGEN;
187 end
188 endcase
189 end
190
191 MEMORY: begin
192 if (`lag(mem_ready)) begin
193 mem_valid = 0;
194 mem_write = 0;
195 end
196 state = FETCH;
197 case (opcode)
198 'h0: begin
199 if (operand[6]) begin
200 if (tx_valid) begin
201 state = MEMORY;
202 end else begin
203 tx_valid = 1;
204 tx_data = acc[7:0];
205 end
206 end
207 if (operand[7]) begin
208 if (`lag(rx_valid)) begin
209 rx_ready = 0;
210 acc = {{(DATA_BITS-8){1'b0}}, `lag(rx_data)};
211 end else begin
212 state = MEMORY;
213 end
214 end
215 end
216 'h2: begin
217 if (`lag(mem_read_valid)) begin
218 acc = acc + `lag(mem_read_data);
219 end else begin
220 state = MEMORY;
221 end
222 end
223 endcase
224 end
225
226 HALT: $finish;
227 endcase
228 end
229end
230
231endmodule