Add diagrams and pictures
[clump.git] / processor_4.v
1 `include "asciihex.v"
2 `include "generic_fifo_sc_a.v"
3 `include "gc.v"
4 `include "ram.v"
5 `include "rom.v"
6 `include "prescaler.v"
7 `include "single_trigger.v"
8 `include "uart.v"
9
10 `define INST_JPZ 4'b0111
11 `define INST_JP 4'b0110
12 `define INST_STM 4'b0101
13 `define INST_LDM 4'b0100
14 `define INST_SUB 4'b0011
15 `define INST_ADD 4'b0010
16 `define INST_LDI 4'b0001
17 `define INST_HALT 4'b0000
18 `define INST_READ 4'b1000
19 `define INST_WRITE 4'b1001
20 `define INST_CONS 4'b1010
21 `define INST_LDQ 4'b1110
22 `define INST_RDQ 4'b1100
23 `define INST_CAR 4'b1111
24 `define INST_CDR 4'b1101
25
26 `define GCOP_NOP 4'd0
27 `define GCOP_CDR 4'd1
28 `define GCOP_CAR 4'd2
29 `define GCOP_CDRQ 4'd3
30 `define GCOP_CARQ 4'd4
31 `define GCOP_CARR 4'd5
32 `define GCOP_CDRRX 4'd6
33 `define GCOP_CARRX 4'd7
34 `define GCOP_CDRQX 4'd8
35 `define GCOP_CONS 4'd9
36 `define GCOP_XCONS 4'd10
37 `define GCOP_RPLACDR 4'd11
38 `define GCOP_LDQ 4'd12
39 `define GCOP_RDQ 4'd13
40 `define GCOP_RDQA 4'd14
41 `define GCOP_RDQCDRRX 4'd15
42
43 // This is a simple four bit accumulator machine. It is a Havard architecture with separate
44 // program and user memory address spaces.
45
46 module PROCESSOR (input clk, output [4:0] led, output uart_tx, input uart_rx);
47 // storage unit
48 reg [7:0] Ein;
49 wire [7:0] Eout;
50 reg [3:0] gcop = 4'b0;
51 wire [6:0] ostate;
52 wire step_eval;
53
54 reg reading_E = 0;
55
56 // Handle running
57
58 reg running = 1;
59
60 // Generate eval and gc clocks
61
62 reg gc_clock = 0;
63 wire eval_clock = !gc_clock & step_eval;
64
65 always @ (posedge clk)
66 gc_clock <= !gc_clock;
67
68 GC gc (.clk(gc_clock), .mclk(clk), .Ein(Ein), .Eout(Eout), .gcop(gcop), .ostate(ostate), .step_eval(step_eval));
69
70 // Handle halt
71
72 reg halt = 0;
73
74 always @ (posedge eval_clock) begin
75 if (inst == `INST_HALT)
76 halt <= 1;
77
78 if (!running)
79 halt <= 0;
80 end
81
82 // UART outputs
83 wire uart_rx_signal;
84 wire [7:0] uart_rx_byte;
85 wire uart_is_receiving;
86 wire uart_is_transmitting;
87 wire uart_rx_error;
88
89 // Handle program space
90 wire [7:0] programOut;
91
92 wire [3:0] inst = programOut[7:4];
93 wire [3:0] argu = programOut[3:0];
94
95 ROM programMemory (.clk(clk), .addr(pc), .data(programOut));
96
97 // Input logic
98 wire [3:0] fifo_in;
99 wire [3:0] fifo_out;
100 wire fifo_full;
101 wire fifo_empty;
102 wire fifo_re = eval_clock & inst == `INST_READ & !fifo_empty;
103 wire fifo_we = uart_rx_signal & !fifo_full;
104
105 ascii_to_hex a2h (.ascii({1'b0, uart_rx_byte[6:0]}), .hex(fifo_in));
106
107 generic_fifo_sc_a #(.dw(4), .aw(4)) fifo
108 (.clk(clk),
109 .rst(1'b1),
110 .re(fifo_re),
111 .we(fifo_we),
112 .din(fifo_in),
113 .dout(fifo_out),
114 .full(fifo_full),
115 .empty(fifo_empty));
116
117 // Output logic
118 reg started_writing = 0;
119
120 always @ (posedge eval_clock) begin
121 if (started_writing)
122 started_writing <= 0;
123 else if (inst == `INST_WRITE & !uart_is_transmitting)
124 started_writing <= 1;
125 end
126
127 // Handle PC
128 reg [3:0] pc = 0;
129
130 wire [3:0] next = pc + 4'b0001;
131 wire [3:0] prev = pc + 4'b1111;
132
133 wire [3:0] newPc =
134 (inst == `INST_JP) ? argu :
135 (inst == `INST_JPZ) & (accum == 4'b0000) ? argu :
136 started_writing ? next :
137 (inst == `INST_WRITE) ? pc :
138 (inst == `INST_READ) & !fifo_re ? pc :
139 (inst == `INST_RDQ) & !reading_E ? pc :
140 (inst != `INST_HALT) ? next :
141 pc;
142
143 always @ (posedge eval_clock) begin
144 pc <= newPc;
145 end
146
147 // Handle user memory
148 wire [3:0] userMemoryOut;
149
150 RAM #(.DATA_BITS(4),.ADDRESS_BITS(4)) userMemory (.clk(clk), .write(eval_clock & (inst == `INST_STM)), .addr(argu), .in_data(accum), .out_data(userMemoryOut));
151
152 // Handle accumulator
153 reg [3:0] accum = 0;
154
155 wire [3:0] newAccum =
156 (inst == `INST_LDI) ? argu :
157 (inst == `INST_ADD) ? accum + argu :
158 (inst == `INST_SUB) ? accum - argu :
159 (inst == `INST_LDM) ? userMemoryOut :
160 fifo_re ? fifo_out :
161 reading_E ? Eout[3:0] :
162 accum;
163
164 always @ (posedge eval_clock) begin
165 accum <= newAccum;
166 end
167
168 // UART logic
169 wire uart_tx_signal = started_writing;
170 wire [7:0] uart_tx_byte;
171
172 hex_to_ascii h2a (.hex(accum), .ascii(uart_tx_byte));
173
174 // 300 baud uart
175 uart #(.CLOCK_DIVIDE(5)) uart (.clk(clk), .rx(uart_rx), .tx(uart_tx), .transmit(uart_tx_signal), .tx_byte(uart_tx_byte), .received(uart_rx_signal), .rx_byte(uart_rx_byte), .is_receiving(uart_is_receiving), .is_transmitting(uart_is_transmitting), .recv_error (uart_rx_error));
176
177 // GC logic
178 always @ (posedge eval_clock) begin
179 if (reading_E) begin
180 reading_E <= 0;
181 gcop <= `GCOP_NOP;
182 end else begin
183 if(inst == `INST_CONS) begin
184 Ein <= {4'b0, accum};
185 gcop <= `GCOP_CONS;
186 end else if(inst == `INST_LDQ) begin
187 Ein <= {4'b0, accum};
188 gcop <= `GCOP_LDQ;
189 end else if(inst == `INST_RDQ) begin
190 Ein <= 8'b0;
191 reading_E <= 1;
192 gcop <= `GCOP_RDQ;
193 end else if(inst == `INST_CAR) begin
194 Ein <= {4'b0, accum};
195 gcop <= `GCOP_CAR;
196 end else if(inst == `INST_CDR) begin
197 Ein <= {4'b0, accum};
198 gcop <= `GCOP_CDR;
199 end else begin
200 Ein <= 8'b0;
201 gcop <= `GCOP_NOP;
202 end
203 end
204 end
205
206 // Assign the outputs
207
208 /* assign led[0] = uart_tx;
209 assign led[1] = uart_is_transmitting;
210 assign led[2] = uart_is_receiving;
211 assign led[3] = uart_rx_signal;
212 assign led[4] = uart_rx_error;
213 assign led[5] = fifo_empty;
214 assign led[6] = fifo_full;
215 assign led[7] = fifo_re;
216 assign led[7:4] = Ein[3:0];
217 assign led[3:0] = Eout[3:0];
218 // assign led[15:8] = programOut;
219 // assign led[15:8] = uart_rx_byte;
220 assign led[13:8] = ostate;
221 assign led[19:16] = pc;
222 assign led[23:20] = accum;
223 assign indicators = {1'b0, (!running & `EXECUTE_BUTTON) | running_clk, halt, running & !halt};*/
224
225 assign led[0] = eval_clock;
226 assign led[1] = uart_is_transmitting;
227 assign led[2] = uart_is_receiving;
228 assign led[3] = recv_error;
229 endmodule
This page took 0.027078 seconds and 4 git commands to generate.