2 `include "generic_fifo_sc_a.v"
7 `include "single_trigger.v"
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
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
43 // This is a simple four bit accumulator machine. It is a Havard architecture with separate
44 // program and user memory address spaces.
46 module PROCESSOR (input clk, output [4:0] led, output uart_tx, input uart_rx);
50 reg [3:0] gcop = 4'b0;
60 // Generate eval and gc clocks
63 wire eval_clock = !gc_clock & step_eval;
65 always @ (posedge clk)
66 gc_clock <= !gc_clock;
68 GC gc (.clk(gc_clock), .mclk(clk), .Ein(Ein), .Eout(Eout), .gcop(gcop), .ostate(ostate), .step_eval(step_eval));
74 always @ (posedge eval_clock) begin
75 if (inst == `INST_HALT)
84 wire [7:0] uart_rx_byte;
85 wire uart_is_receiving;
86 wire uart_is_transmitting;
89 // Handle program space
90 wire [7:0] programOut;
92 wire [3:0] inst = programOut[7:4];
93 wire [3:0] argu = programOut[3:0];
95 ROM programMemory (.clk(clk), .addr(pc), .data(programOut));
102 wire fifo_re = eval_clock & inst == `INST_READ & !fifo_empty;
103 wire fifo_we = uart_rx_signal & !fifo_full;
105 ascii_to_hex a2h (.ascii({1'b0, uart_rx_byte[6:0]}), .hex(fifo_in));
107 generic_fifo_sc_a #(.dw(4), .aw(4)) fifo
118 reg started_writing = 0;
120 always @ (posedge eval_clock) begin
122 started_writing <= 0;
123 else if (inst == `INST_WRITE & !uart_is_transmitting)
124 started_writing <= 1;
130 wire [3:0] next = pc + 4'b0001;
131 wire [3:0] prev = pc + 4'b1111;
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 :
143 always @ (posedge eval_clock) begin
147 // Handle user memory
148 wire [3:0] userMemoryOut;
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));
152 // Handle accumulator
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 :
161 reading_E ? Eout[3:0] :
164 always @ (posedge eval_clock) begin
169 wire uart_tx_signal = started_writing;
170 wire [7:0] uart_tx_byte;
172 hex_to_ascii h2a (.hex(accum), .ascii(uart_tx_byte));
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));
178 always @ (posedge eval_clock) begin
183 if(inst == `INST_CONS) begin
184 Ein <= {4'b0, accum};
186 end else if(inst == `INST_LDQ) begin
187 Ein <= {4'b0, accum};
189 end else if(inst == `INST_RDQ) begin
193 end else if(inst == `INST_CAR) begin
194 Ein <= {4'b0, accum};
196 end else if(inst == `INST_CDR) begin
197 Ein <= {4'b0, accum};
206 // Assign the outputs
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};*/
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;