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

Subversion Repositories blue

[/] [blue/] [trunk/] [blue8/] [top.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 wd5gnr
/*
2
    This file is part of Blue8.
3
 
4
    Foobar is free software: you can redistribute it and/or modify
5
    it under the terms of the GNU Lesser General Public License as published by
6
    the Free Software Foundation, either version 3 of the License, or
7
    (at your option) any later version.
8
 
9
    Foobar is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU Lesser General Public License for more details.
13
 
14
    You should have received a copy of the GNU Lesser General Public License
15
    along with Blue8.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
    Blue8 by Al Williams alw@al-williams.com
18
 
19
*/
20
 
21
// OK this is the blue CPU -- Williams
22
 
23
 `default_nettype        none
24
 
25
 
26
 module blue(input wire clear,input wire clkin, output [15:0] accout, input wire start,
27
             input wire stop, input wire exam, input wire deposit, output wire [11:0] pcout,
28
                                 input wire [15:0] swreg, input wire swloadpc, output wire [15:0] irout, output wire running,
29
                                 /* memory interface */
30
                                 output wire [11:0] xmaddress, inout wire [15:0] xmdata, output wire xmwrite,
31
                                 output wire xmsend,
32
                                 output wire clk, output reg Q
33
 
34
                                 );
35
   wire [15:0]    bus;
36
   wire [15:0]    mabus;  // memory address bus (11:0 significant)
37
   wire [15:0]    aluzbus;
38
   wire [15:0]    aluybus;
39
   wire [8:1]    cp;  // clock pulses
40
        wire [8:1] cpw;  // write clock pulses
41
   wire [15:0]    ibus;
42
   wire [15:0]    accbus;
43
   wire mclear;
44
        wire sendxor, sendx2, sendhalf;
45
        wire ihlt, ophlt, opxor, opand, opior, opnot, oplda, opsta, opsrj, opjmp, opldx;
46
        wire opral, opnop, opinc, opdec, opskip, opspn, opq, opqtog, opsub, opcmp, opldi, oprar, opidx;
47
        wire opstx, opjmpa, opswap, oplds, oppush, oppop, opframe, opldxa;
48
 
49
 
50
 
51
 
52
   wor           sendpc,writemar, writeZ,msend,mwrite, sendone,writeY, sendsum, senddiff;
53
   wor           sendir, sendbar, sendand, sendacc;
54
   wor            writeacc, sendor, sendffff, sendidx, writeidx;
55
        wire writeir;
56
   wire          DTA, ARITH, REF;
57
   wor s2bus, writepc;
58
        wire doexam, dodep;
59
        wire sendzero;
60
        wor abortcycle;
61
        wire opadd; // ought to provide the others here too
62
        wire overflow, aluzero, carry;
63
        reg zflag, oflag, cflag;
64
        wire [11:0] idxbus;
65
        wor writesp, sendsp;
66
 
67
 
68
   assign        accout=accbus;
69
        assign   irout=ibus;
70
 
71
 
72
   // make the data path items
73
   register IR(clk,bus,writeir,bus,sendir,ibus,mclear);
74
   aregister MAR(clk,bus,writemar,,1'b1,mabus[11:0],mclear);
75
        aregister INDEX(clk,bus,writeidx,bus,sendidx,idxbus,mclear);
76
        aregister SP(clk,bus,writesp,bus,sendsp,,mclear);
77
   register Y(clk,bus,writeY,,1'b0,aluybus,mclear);
78
   register Z(clk,bus,writeZ,,1'b0,aluzbus,mclear);
79
//   mem core(clk,mabus,bus,mwrite,bus,msend);
80
   assign xmaddress=mabus;
81
        assign xmdata=mwrite?bus:16'bz;
82
        assign bus=xmsend?xmdata:16'bz;
83
   assign xmwrite=mwrite;
84
        assign xmsend=msend;
85
 
86
   register acc(clk,bus,writeacc,bus,sendacc,accbus,mclear);
87
   aregister pc(clk,bus,writepc,bus,sendpc,pcout,mclear);
88
   one One(sendone,bus);
89
   ffff Ffff(sendffff,bus);
90
        zero Zero(sendzero,bus);
91
 
92
   alu alu(aluybus,aluzbus,bus,sendsum,sendor,sendand,sendxor,sendbar,sendx2,senddiff,sendhalf, overflow,aluzero,carry,cflag);
93
 
94
   wire coverflow, writezf, writecf, writeflag;
95
        wire writepc1;
96
        assign writepc=writepc1;
97
//      assign coverflow=overflow & opadd;  // only overflow on adding
98
 assign coverflow=1'b0;  // we don't halt on overflow anymore
99
 
100
   // TODO: Tried to add abort cycle to let short instructions recycle faster. Doesn't seem to work (yet)
101
 
102
        control ctl(clkin,start,stop,exam,deposit,ihlt,coverflow,cp,cpw,clear,mclear,s2bus,writepc1,swloadpc, doexam,dodep,running,clk,abortcycle);
103
   idecode decoder(ibus,ophlt,opadd,opxor,opand,opior,opnot,oplda,opsta,
104
                   opsrj, opjmp, opldx,  opral, opnop,opinc,opdec, opskip, opspn,opq,opqtog,opsub,opcmp,
105
                        opldi, oprar, opidx, opstx, opjmpa, opswap, oplds, oppush, oppop, opframe, opldxa);
106
 
107
 
108
   always @(posedge clk or posedge mclear) begin                          // manage Q output
109
          if (mclear) Q<=0;
110
          else if (cpw[5]) begin
111
            if (opq) Q<=ibus[0];
112
            else if (opqtog) Q<=~Q;
113
     end
114
          else Q<=Q;
115
        end
116
 
117
   always @(posedge clk or posedge mclear) begin                 // manage z flag (not Z register)
118
          if (mclear) zflag<=1'b0;
119
          else if (writeflag) zflag<=bus[1];
120
          else if ((sendsum|senddiff|sendor|sendand|sendxor|sendbar|sendx2)&(writeacc|writezf)) zflag<=aluzero;
121
          else zflag<=zflag;
122
        end
123
 
124
        always @(posedge clk or posedge mclear) begin           // manage overflow flag
125
          if (mclear) oflag<=1'b0;
126
          else if (writeflag) oflag<=bus[0];
127
          else if (sendsum&writeacc) oflag<=overflow;
128
          else oflag<=oflag;
129
        end
130
 
131
        always @(posedge clk or posedge mclear) begin     // manage carry flag
132
          if (mclear) cflag<=1'b0;
133
          else if (writeflag) cflag<=bus[2];
134
          else if ((sendsum|sendx2|senddiff|sendhalf)&(writeacc|writecf)) cflag<=carry;
135
          else cflag<=cflag;
136
        end
137
 
138
// load pc (switch)
139
   assign bus=s2bus?swreg:16'bz;
140
 
141
   // instructions
142
// first part of F cycle
143
    assign sendpc=cp[1];
144
         assign writemar=cpw[1];
145
         assign writeZ=cpw[1];
146
 
147
 
148
        // So here this was in cp[6] but I moved things and will move this to cp2
149
// which leaves cp5,6,7,8/F free for processing.. placing it before PC++
150
// means the async decoder can be pretty sloppy since the result is not needed until cp5
151
   and u7(msend,cp[2],~(doexam|dodep));
152
        and u7z(sendzero, cp[2],(doexam|dodep));                // assumes NOP or HALT=0
153
   assign writeir=cpw[2];
154
 
155
 
156
         assign sendone=cp[3];
157
         assign writeY=cpw[3];
158
 
159
// writeback PC... cycles 5-8 are free for execute
160
 
161
    assign sendsum=cp[4];
162
         assign writepc=cpw[4];
163
 
164
 
165
// do an exam 
166
   and uex1(msend,cp[5],doexam);
167
        and uex2(writeacc,cpw[5],doexam);
168
 
169
 
170
// do a deposit
171
   and udep1(s2bus,cp[5],dodep);
172
        and udep2(mwrite,cpw[5],dodep);
173
 
174
 
175
// halt instruction 
176
   and u9(ihlt,cp[7],ophlt);
177
 
178
// 2 jump instruction
179
   and u12(sendir,opjmp,cp[5]);
180
   and u13(writepc,opjmp,cpw[5]);
181
 
182
        // abort 6 cycle instructions
183
        and u13x(abortcycle,opjmp|opldx|opstx|opjmpa|opswap|oplds|opnop|opframe|opq|opqtog,cp[5]);
184
        // abort 7 cycle instructions
185
        and u13y(abortcycle, opskip|opspn|opnot|opral|oprar|opidx,cp[6]);
186
 
187
// RAL, NOT, CSA
188
// don't need the next 3 anymore
189
// because I preload ACC to Z in CP5/F
190
//   or u16(nr1,opnot,opral);
191
//   and u17a(sendacc,nr1,cp[7]);
192
//   and u17b(writeZ,nr1,cp[7]);
193
// update: changed CP5/F to execute cycle so now Ido this later 
194
 
195
 
196
// not (pt 2)
197
   and u19a(sendbar,opnot,cp[6]);
198
   and u19b(writeacc,opnot,cpw[6]);
199
// ral, rar
200
   and u20a(sendx2,opral,cp[6]);
201
   and u20c(sendhalf,oprar,cp[6]);
202
   and u20b(writeacc,opral|oprar,cpw[6]);
203
 
204
// skipped input/output TODO
205
 
206
// ARITH, DTA, REF (internal)
207
   assign        ARITH=opand|opxor|opior|opadd|opsub|opcmp;
208
   assign        DTA=ARITH | oplda;
209
   assign        REF=DTA | opsta;
210
 
211
  // for some reason, asserting estate on cp[8] worked in simulation, but 
212
  // in real life, single stepping would halt before E state in a two cycle
213
  // instruction. So that implies an async stop could hold the machine in E state
214
  // moving estate assert to cp[7] fixed this even though sim says no difference
215
 
216
  //V3 moves all 2 cycle instructions to 1 cycle, 
217
//   and u21(estate,REF,F,cp[7]);                 // was cp[8] but no REF instruction uses cp[7] for anything
218
   and u22a(sendir,cp[5], ARITH|((opsta|oplda) & ~ibus[15]));           // ir[15] = 1 for ldax, stax
219
   assign bus=((opsta|oplda) & cp[5]  & ibus[15])?ibus[11:0]+idxbus:16'bz;
220
   and u22b(writemar,REF,cpw[5]);
221
 
222
 
223
   and u23a(sendacc,REF,cp[6]);   // These could be ARITH? DTA/REF don't use Z register, but harmless
224
   and u23b(writeZ,REF,cpw[6]);
225
 
226
//   and u24(msend,DTA,E,cp[5]);
227
// my design does not use cp5/F so I am going to use that
228
// cycle to load Acc to Z in case we want it for future
229
// So in execute phase ACC ->Z 1->Y and no need to do it over
230
// However, since then I have changed the design so that cp5 is
231
// a regular execute slot so this is now specific to the INCA, DECA
232
// NOT and RAL instructions
233
   and u40a(sendacc,opinc|opdec|opnot|opral|oprar,cp[5]);
234
   and u40b(writeZ,opinc|opdec|opnot|opral|oprar,cpw[5]);
235
 
236
 
237
   and u25a(sendacc,opsta,cp[8]);
238
   and u25b(mwrite,opsta,cpw[8]);
239
 
240
   and u26a(msend,oplda,cp[8]);
241
   and u27a(writeacc,oplda,cpw[8]);
242
 
243
   and u28a(msend,ARITH,cp[7]);
244
   and u28b(writeY,ARITH,cpw[7]);
245
 
246
   and u29a(sendsum,opadd,cp[8]);
247
   and u29b(writeacc,opadd,cpw[8]);
248
 
249
   and u29c(senddiff,opsub|opcmp,cp[8]);
250
   and u29d(writeacc,opsub,cpw[8]);
251
        and u29e(writezf, opcmp,  cpw[8]);
252
        and u29f(writecf, opcmp, cpw[8]);
253
 
254
 
255
   and u30a(sendxor,opxor,cp[8]);
256
   and u30b(writeacc,opxor,cpw[8]);
257
 
258
   and u31a(sendor,opior,cp[8]);
259
   and u31b(writeacc,opior,cpw[8]);
260
 
261
   and u32a(sendand,opand,cp[8]);
262
   and u32b(writeacc,opand,cpw[8]);
263
 
264
// Increment and dec instruction -- we already made cp5/F copy ACC->Z
265
   // and Y still has 1 in it, so...
266
// for decrement cp7/F needs to load -1 instead of 1
267
   and u42a(sendffff,opdec,cp[7]);
268
   and u42b(writeY,opdec,cpw[7]);
269
 
270
   and u41a(sendsum,opinc|opdec,cp[8]);
271
   and u41b(writeacc,opinc|opdec,cpw[8]);
272
 
273
 
274
        // skip instructions    (note OK to reuse ALU because C Z and O are latched on specific instructions
275
        wire [2:0] flags;
276
        assign flags={cflag, zflag, oflag};
277
        and u43a(sendpc,opskip,cp[5]);
278
        and u43b(writeZ,opskip,cpw[5]);
279
        and u44a(sendsum,opskip,((ibus[3]?~flags:flags)&ibus[2:0])!=0,cp[6]);
280
// -- another way:   assign bus=opskip & cp[6]?skippc:16'bz;
281
        and u44b(writepc,opskip,((ibus[3]?~flags:flags)&ibus[2:0])!=0,cpw[6]);
282
 
283
// Could write skip on sign and get rid of JMA
284
   and u45a(sendpc,opspn,cp[5]);
285
        and u45b(writeZ, opspn,cpw[5]);
286
        and u46a(sendsum,opspn,ibus[0]?~accbus[15]:accbus[15],cp[6]);
287
// -- another way   assign bus=(opspn & cp[6])?skippc:16'bz;
288
        and u46b(writepc,opspn,ibus[0]?~accbus[15]:accbus[15],cpw[6]);
289
 
290
// LDI
291
   and u47a(sendpc,cp[5],opldi);
292
   and u47b(writemar,cpw[5],opldi);
293
   and u47c(writeZ,cpw[5],opldi);
294
   and u48a(sendsum,cp[6],opldi);
295
   and u48b(writepc,cpw[6],opldi);
296
   and u49a(msend,opldi,cp[7]);
297
   and u49b(writeacc,opldi,cpw[7]);
298
 
299
// LDX
300
   and u50a(sendir,cp[5],opldx);
301
        and u50aa(sendacc,cp[5],opldxa);
302
        and u50b(writeidx,cpw[5],opldx|opldxa);
303
 
304
 
305
// INCX/DECX
306
        and u51a(sendidx,cp[5],opidx);
307
        and u51b(writeZ,cpw[5],opidx);
308
        and u52a(sendsum,cp[6],opidx,~ibus[0]);
309
        and u52b(senddiff,cp[6],opidx,ibus[0]);
310
        and u52c(writeidx,cpw[6],opidx);
311
 
312
// STX
313
   and u53a(sendidx,cp[5],opstx);
314
        and u53b(writeacc,cpw[5],opstx);
315
 
316
// JMPA
317
   and u54a(sendacc,cp[5],opjmpa);
318
        and u54b(writepc,cpw[5],opjmpa);
319
 
320
// SWAP
321
   assign bus[15:8]=opswap&cp[5]?accbus[7:0]:8'bz;
322
        assign bus[7:0]=opswap&cp[5]?accbus[15:8]:8'bz;
323
        and u55(writeacc,cpw[5],opswap);
324
 
325
// LDS
326
   and u56a(sendir,cp[5],oplds);
327
        and u56b(writesp,cpw[5],oplds);
328
 
329
// PUSH and CALL
330
   wire pushcall;
331
        assign pushcall=oppush|opsrj;
332
        and u57a(sendsp,cp[5],pushcall);
333
        and u57b(writemar,cpw[5],pushcall);
334
        and u57c(writeZ,cpw[5],pushcall);
335
        and u58a(sendacc,cp[6],oppush, ibus[1:0]==2'b00);
336
        and u58aa(sendidx,cp[6],oppush, ibus[1:0]==2'b10);
337
   assign bus=(cp[6]&oppush&ibus[1:0]==2'b11)?({13'b0, flags}):16'bz;
338
        and u58b(sendpc, cp[6], opsrj);
339
        and u58c(mwrite, cpw[6], pushcall);
340
        and u59a(senddiff,cp[7], pushcall);
341
        and u59b(writesp,cpw[7], pushcall);
342
        and u59c(sendir,cp[8],opsrj);
343
        and u59d(writepc, cpw[8],opsrj);
344
 
345
// POP and RET
346
 
347
   and u60a(sendsp,cp[5],oppop);
348
        and u60b(writeZ,cpw[5], oppop);
349
        and u61a(sendsum,cp[6],oppop);
350
        and u61b(writesp, cpw[6], oppop);
351
        and u61c(writemar,cpw[6], oppop);
352
        and u62a(msend, cp[7], oppop);
353
        and u62b(writeacc, cpw[7], oppop, ibus[1:0]==2'b00);
354
        and u62c(writepc, cpw[7], oppop, ibus[1:0]==2'b01);
355
        and u62d(writeidx, cpw[7], oppop, ibus[1:0]==2'b10);
356
        and u63a(writeflag, cp[7], oppop, ibus[1:0]==2'b11);  // pop flag -- not sure this works?  
357
 
358
 // frame
359
   and u64a(sendsp,cp[5],opframe);
360
        and u64b(writeidx,cpw[5],opframe);
361
 
362
endmodule
363
 

powered by: WebSVN 2.1.0

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