OpenCores
URL https://opencores.org/ocsvn/brainfuckcpu/brainfuckcpu/trunk

Subversion Repositories brainfuckcpu

[/] [brainfuckcpu/] [trunk/] [rtl/] [brainfuck_cpu.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 akaminski
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Company: 
4
// Engineer: Aleksander Kaminski
5
// 
6
// Create Date:    01:23:37 07/08/2014 
7
// Design Name:         Braindfuck CPU
8
// Module Name:    brainfuck_cpu 
9
// Project Name: 
10
// Target Devices: 
11
// Tool versions: 
12
// Description: 
13
//
14
// Dependencies: 
15
//
16
// Revision: 
17
// Revision 0.01 - File Created
18
// Additional Comments: 
19
// 000 = <
20
// 001 = >
21
// 010 = +
22
// 011 = -
23
// 100 = ,
24
// 101 = .
25
// 110 = [
26
// 111 = ]
27
//////////////////////////////////////////////////////////////////////////////////
28
module brainfuck_cpu #(parameter DATA_ADDR_WIDTH = 8, ROM_ADDR_WIDTH = 12, STACK_DEPTH = 4)
29
        (
30
        input clk,
31
        input rst,
32
        input [7:0] data_i,
33
        output [7:0] data_o,
34
        input [2:0] rom_i,
35
        output [DATA_ADDR_WIDTH-1:0] data_addr_o,
36
        output [ROM_ADDR_WIDTH-1:0] rom_addr_o,
37
        output reg rd,
38
        output reg wr,
39
        output reg mreq,
40
        output reg ioreq,
41
        input ready
42
        );
43
 
44
// FSM states
45
 
46
        localparam      RAM_CLEAR = 3'b001,
47
                                        RUN = 3'b010,
48
                                        UPDATE_DATA = 3'b100,
49
                                        INSTANT_ZERO_EXEPTION_RECOVERY = 3'b101,
50
                                        JUMP_RECOVERY = 3'b110;
51
 
52
// Declarations
53
 
54
        reg [2:0] ir;
55
        reg [7:0] data_reg;
56
        reg [ROM_ADDR_WIDTH-1:0] pc;
57
        reg [DATA_ADDR_WIDTH-1:0] pointer;
58
        reg [clogb2(STACK_DEPTH)-1:0] sp;
59
        reg [ROM_ADDR_WIDTH-1:0] stack [0:STACK_DEPTH-1];
60
 
61
        reg [2:0] fsm_state;
62
        reg [2:0] fsm_next;
63
 
64
        reg ir_load;
65
 
66
        reg data_reg_load;
67
        reg data_reg_inc;
68
        reg data_reg_dec;
69
 
70
        reg stack_load;
71
        reg sp_inc;
72
        reg sp_dec;
73
 
74
        reg pc_inc;
75
        reg pc_load;
76
 
77
        reg pointer_inc;
78
        reg pointer_dec;
79
 
80
        integer i;
81
 
82
//      Instruction fetching
83
 
84
        always @(posedge clk, posedge rst) begin
85
                if(rst)
86
                        ir <= 0;
87
                else if(ir_load)
88
                        ir <= rom_i;
89
        end
90
 
91
// Current data register
92
 
93
        always @(posedge clk, posedge rst) begin
94
                if(rst)
95
                        data_reg <= 0;
96
                else begin
97
                        if(data_reg_inc)
98
                                data_reg <= data_reg + 1;
99
                        else if(data_reg_dec)
100
                                data_reg <= data_reg - 1;
101
                        else if(data_reg_load)
102
                                data_reg <= data_i;
103
                end
104
        end
105
 
106
        assign data_o = data_reg;
107
 
108
// Stack
109
 
110
        always @(posedge clk) begin
111
                for( i=0 ; i<STACK_DEPTH ; i=i+1 )
112
                        stack[i] <= stack[i];
113
                if(stack_load)
114
                        stack[sp] <= pc;
115
        end
116
 
117
//      Stack pointer
118
 
119
        always @(posedge clk, posedge rst) begin
120
                if(rst)
121
                        sp <= 0;
122
                else if(sp_inc)
123
                        sp <= sp + 1'b1;
124
                else if(sp_dec)
125
                        sp <= sp - 1'b1;
126
        end
127
 
128
// Program counter
129
 
130
        always @(posedge clk, posedge rst) begin
131
                if(rst)
132
                        pc <= 0;
133
                else if(pc_inc)
134
                        pc <= pc + 1;
135
                else if(pc_load)
136
                        pc <= stack[sp-1];
137
        end
138
 
139
        assign rom_addr_o = pc;
140
 
141
// Pointer
142
 
143
        always @(posedge clk, posedge rst) begin
144
                if(rst)
145
                        pointer <= 0;
146
                else if(pointer_inc)
147
                        pointer <= pointer + 1;
148
                else if(pointer_dec)
149
                        pointer <= pointer - 1;
150
        end
151
 
152
        assign data_addr_o = pointer;
153
 
154
// FSM
155
 
156
        always @(posedge clk, posedge rst) begin
157
                if(rst)
158
                        fsm_state <= RAM_CLEAR;
159
                else
160
                        fsm_state <= fsm_next;
161
        end
162
 
163
        always @(*) begin
164
                ir_load <= 1'b0;
165
                data_reg_load <= 1'b0;
166
                data_reg_inc <= 1'b0;
167
                data_reg_dec <= 1'b0;
168
                stack_load <= 1'b0;
169
                sp_inc <= 1'b0;
170
                sp_dec <= 1'b0;
171
                pc_inc <= 1'b0;
172
                pc_load <= 1'b0;
173
                pointer_inc <= 1'b0;
174
                pointer_dec <= 1'b0;
175
                wr <= 1'b0;
176
                rd <= 1'b0;
177
                mreq <= 1'b0;
178
                ioreq <= 1'b0;
179
 
180
                case(fsm_state)
181
                        RAM_CLEAR: begin
182
                                wr <= 1'b1;
183
                                mreq <= 1'b1;
184
                                fsm_next <= RAM_CLEAR;
185
 
186
                                if(ready) begin
187
                                        pointer_inc <= 1'b1;
188
                                        if(&pointer) begin
189
                                                ir_load <= 1'b1;
190
                                                pc_inc <= 1'b1;
191
                                                fsm_next <= RUN;
192
                                        end
193
                                end
194
                        end
195
 
196
                        RUN: begin
197
                                case(ir)
198
                                        3'b000: begin           //<
199
                                                wr <= 1'b1;
200
                                                mreq <= 1'b1;
201
 
202
                                                if(ready) begin
203
                                                        pointer_dec <= 1'b1;
204
                                                        ir_load <= 1'b1;
205
                                                        pc_inc <= 1'b1;
206
                                                        fsm_next <= UPDATE_DATA;
207
                                                end
208
                                                else
209
                                                        fsm_next <= RUN;
210
                                        end
211
 
212
                                        3'b001: begin           //>
213
                                                wr <= 1'b1;
214
                                                mreq <= 1'b1;
215
 
216
                                                if(ready) begin
217
                                                        pointer_inc <= 1'b1;
218
                                                        ir_load <= 1'b1;
219
                                                        pc_inc <= 1'b1;
220
                                                        fsm_next <= UPDATE_DATA;
221
                                                end
222
                                                else
223
                                                        fsm_next <= RUN;
224
                                        end
225
 
226
                                        3'b010: begin           //+
227
                                                ir_load <= 1'b1;
228
                                                pc_inc <= 1'b1;
229
                                                data_reg_inc <= 1'b1;
230
                                                fsm_next <= RUN;
231
                                        end
232
 
233
                                        3'b011: begin           //-
234
                                                ir_load <= 1'b1;
235
                                                pc_inc <= 1'b1;
236
                                                data_reg_dec <= 1'b1;
237
                                                fsm_next <= RUN;
238
                                        end
239
 
240
                                        3'b100: begin           //,
241
                                                rd <= 1'b1;
242
                                                ioreq <= 1'b1;
243
                                                fsm_next <= RUN;
244
 
245
                                                if(ready) begin
246
                                                        data_reg_load <= 1'b1;
247
                                                        ir_load <= 1'b1;
248
                                                        pc_inc <= 1'b1;
249
                                                end
250
                                        end
251
 
252
                                        3'b101: begin           //.
253
                                                wr <= 1'b1;
254
                                                ioreq <= 1'b1;
255
                                                fsm_next <= RUN;
256
 
257
                                                if(ready) begin
258
                                                        ir_load <= 1'b1;
259
                                                        pc_inc <= 1'b1;
260
                                                end
261
                                        end
262
 
263
                                        3'b110: begin           //[
264
                                                ir_load <= 1'b1;
265
                                                pc_inc <= 1'b1;
266
 
267
                                                if(data_reg == 7'b0)
268
                                                        fsm_next <= INSTANT_ZERO_EXEPTION_RECOVERY;
269
                                                else begin
270
                                                        sp_inc <= 1'b1;
271
                                                        stack_load <= 1'b1;
272
                                                        fsm_next <= RUN;
273
                                                end
274
                                        end
275
 
276
                                        3'b111: begin           //]
277
                                                if(~(data_reg == 7'b0)) begin
278
                                                        pc_load <= 1'b1;
279
                                                        fsm_next <= JUMP_RECOVERY;
280
                                                end
281
                                                else begin
282
                                                        ir_load <= 1'b1;
283
                                                        pc_inc <= 1'b1;
284
                                                        sp_dec <= 1'b1;
285
                                                        fsm_next <= RUN;
286
                                                end
287
                                        end
288
 
289
                                endcase
290
 
291
                        end
292
 
293
                        UPDATE_DATA: begin
294
                                rd <= 1'b1;
295
                                mreq <= 1'b1;
296
 
297
                                if(ready) begin
298
                                        data_reg_load <= 1'b1;
299
                                        fsm_next <= RUN;
300
                                end
301
                                else
302
                                        fsm_next <= UPDATE_DATA;
303
                        end
304
 
305
                        INSTANT_ZERO_EXEPTION_RECOVERY: begin
306
                                ir_load <= 1'b1;
307
                                pc_inc <= 1'b1;
308
 
309
                                if(ir == 3'b111)
310
                                        fsm_next <= RUN;
311
                                else
312
                                        fsm_next <= INSTANT_ZERO_EXEPTION_RECOVERY;
313
                        end
314
 
315
                        JUMP_RECOVERY: begin
316
                                ir_load <= 1'b1;
317
                                pc_inc <= 1'b1;
318
                                fsm_next <= RUN;
319
                        end
320
 
321
                        default: fsm_next <= RAM_CLEAR;
322
 
323
                endcase
324
        end
325
 
326
//      Function clogb2
327
 
328
        function integer clogb2;
329
                input [31:0] value;
330
                integer         i;
331
                begin
332
                        clogb2 = 0;
333
                        for(i = 0; 2**i < value; i = i + 1)
334
                                clogb2 = i + 1;
335
                end
336
        endfunction
337
 
338
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.