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

Subversion Repositories sub86

[/] [sub86/] [trunk/] [sub86.v] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 ultro
module sub86( CLK, RSTN, IA, ID, A, D, Q, WEN,BEN,CE,RD,INT );
2
input         CLK,RSTN,CE,INT;
3
input  [15:0] ID;
4
input  [31:0] D;
5 2 ultro
output [31:0] IA;
6
output [31:0] A;
7
output [31:0] Q;
8 11 ultro
output        WEN,RD;
9 2 ultro
output  [1:0] BEN;
10
reg    [31:0] EAX,EBX,ECX,EDX,EBP,ESP,PC,regsrc,regdest,alu_out;
11 5 ultro
reg     [5:0] state,nstate;
12 2 ultro
reg     [2:0] src,dest;
13 12 ultro
reg           INTreg,WR,RD,cry,ncry,prefx,nprefx,cmpr,eqF,gF,lF,aF,bF;
14
wire          INTvalid,nncry,neqF,ngF,nlF,naF,nbF,divF1,divF2;
15 7 ultro
wire   [31:0] pc_ja,pc_jae,pc_jb,pc_jbe,pc_jg,pc_jge,pc_jl,pc_jle,pc_eq,pc_jp,pc_neq,pc_sh;
16 5 ultro
wire   [31:0] Sregsrc,Zregsrc,incPC,sft_out,smlEAX,smlECX;
17 3 ultro
wire   [32:0] adder_out,sub_out;
18 5 ultro
wire    [4:0] EBX_shtr;
19
wire signed [31:0] ssregsrc, ssregdest;
20
`define fetch 6'b111111
21
`define jmp   6'b000001
22
`define jmp2  6'b000010
23
`define jge   6'b000011
24
`define jge2  6'b000100
25
`define imm   6'b000101
26
`define imm2  6'b000110
27
`define lea   6'b000111
28
`define lea2  6'b001000
29
`define call  6'b001001
30
`define call2 6'b001010
31
`define ret   6'b001011
32
`define ret2  6'b001100
33
`define shift 6'b001110
34
`define jg    6'b001111
35
`define jg2   6'b010000
36
`define jl    6'b010001
37
`define jl2   6'b010010
38
`define jle   6'b010011
39
`define jle2  6'b010100
40
`define je    6'b010101
41
`define je2   6'b010110
42
`define jne   6'b010111
43
`define jne2  6'b011000
44
`define mul   6'b011001
45
`define mul2  6'b011010
46
`define shft2 6'b011011
47
`define jb    6'b011100
48
`define jb2   6'b011101
49
`define jbe   6'b011110
50
`define jbe2  6'b011111
51
`define ja    6'b100000
52
`define ja2   6'b100001
53
`define jae   6'b100010
54
`define jae2  6'b100011
55
`define sml1  6'b100100
56
`define sml2  6'b100101
57
`define sml3  6'b100110
58
`define sml4  6'b100111
59 6 ultro
`define sdv1  6'b101000
60
`define sdv2  6'b101001
61
`define sdv3  6'b101010
62
`define sdv4  6'b101011
63
`define div1  6'b101100
64 7 ultro
`define leas  6'b101101
65 8 ultro
`define calla 6'b101110
66
`define calla2 6'b101111
67 9 ultro
`define shft3 6'b110000
68 12 ultro
`define int1  6'b110001
69
`define int2  6'b110010
70 5 ultro
`define init  6'b000000
71 8 ultro
 
72 5 ultro
 always @(posedge CLK)
73 12 ultro
      casex ({RSTN,INT,((RD|WR)&CE)}) // interrupt control
74
        3'b0xx   : INTreg <= 1'b0;
75
        3'b11x   : INTreg <= 1'b1;
76
        3'b1x1   : INTreg <= 1'b0;
77
        default  : INTreg <= INTreg;
78
      endcase
79
 
80
 always @(posedge CLK)
81 7 ultro
   if ((CE ==1'b1) || (RSTN ==1'b0))
82 5 ultro
     begin
83
      case (state) // cry control
84 6 ultro
         `sml1,`sdv1: cry <= EAX[31] ^ ECX[31];
85
         `div1      : cry <= 1'b0;
86
         default    : cry <= ncry & RSTN;
87 5 ultro
      endcase
88
      prefx <= nprefx & RSTN;
89
      state <= nstate & {6{RSTN}};
90
      if (cmpr) begin eqF <= neqF & RSTN; lF <= nlF & RSTN; gF <= ngF & RSTN;
91 7 ultro
                      bF  <=  nbF & RSTN; aF <= naF & RSTN; end
92 5 ultro
           else begin eqF <=  eqF & RSTN; lF <=  lF & RSTN; gF <=  gF & RSTN;
93
                      bF  <=   bF & RSTN; aF <=  aF & RSTN; end
94
      case(state)  // EAX control
95 7 ultro
        `init       : EAX <= 32'b0;
96 5 ultro
        `mul,`sml2  : EAX <= {EAX[30:0],1'b0};
97
        `mul2       : EAX <= EBX;
98
        `sml1       : EAX <= smlEAX;
99
        `sml3       : if (cry==1'b0) EAX <= EBX; else EAX <= ((~EBX) + 1'b1);
100 6 ultro
        `sdv1,`div1 : EAX <= 32'b0;
101
        `sdv3       : if (nlF==1'b0) EAX <= EAX + ( 1 << EBX_shtr); else EAX <=EAX;
102
        `sdv4       : if (cry==1'b1) EAX <= ((~EAX) + 1'b1); else EAX <= EAX;
103 5 ultro
        default: if (dest==3'b000) EAX <= alu_out; else EAX<=EAX;
104
      endcase
105
      case(state)  // EBX control
106 7 ultro
        `init       : EBX <= 32'b0;
107 5 ultro
        `jmp , `jg, `jge , `jl, `jle, `je, `jne, `imm, `call, `jb,`jbe,`ja,`jae,
108
        `lea        : EBX<={EBX[31:16],ID[7:0],ID[15:8]};
109 7 ultro
        `leas       : EBX<={ {24{ID[15]}} , ID[15:8]}+EBP;
110 5 ultro
        `imm2       : EBX<={ID[7:0],ID[15:8], EBX[15:0]};
111
        `lea2       : EBX<={ID[7:0],ID[15:8], EBX[15:0]}+EBP;
112
        `mul,`sml2  : if (ECX[0] == 1'b1) EBX <= EAX+EBX; else EBX <= EBX;
113
        `shift      : EBX<={EBX[31:5],EBX_shtr};
114 6 ultro
        `sdv1       : EBX<={EAX[31],ECX[31],EBX[29:0]};
115
        `div1       : EBX<={          2'b00,EBX[29:0]};
116
        `sdv2       : if (divF1==1'b0 ) EBX <= {EBX[31:5],(EBX[4:0]+1'b1)}; else EBX <= EBX;
117
        `sdv3       : if (divF1==1'b1 ) EBX <= {EBX[31:5],EBX_shtr}; else EBX <= EBX;
118 13 ultro
        `fetch      : if (ID[15:8] == 8'hb3) EBX<= {EBX[31:24],ID[7:0]};
119 7 ultro
                 else if (dest==3'b011) EBX <= alu_out; else EBX <= EBX;
120 13 ultro
        default     : EBX <= EBX;
121 5 ultro
      endcase
122
      case(state)  // ECX control
123 7 ultro
        `init       : ECX <= 32'b0;
124 5 ultro
        `mul,`sml2  : ECX <= {1'b0,ECX[31:1]};
125 6 ultro
        `sml1,`sdv1 : ECX <= smlECX;
126
        `div1       : ECX <= ECX;
127
        `sdv2       : if (divF1==1'b0 ) ECX <= {ECX[30:0],1'b0}; else ECX<=ECX;
128
        `sdv3       : if((divF1==1'b1 ) && (divF2==1'b0)) ECX <= {1'b0,ECX[31:1]}; else ECX<=ECX;
129
        `sdv4       : if (EBX[30] == 1'b1) ECX <= ((~ECX) + 1); else ECX<=ECX;
130 5 ultro
        default     : if (dest==3'b001) ECX <= alu_out; else ECX<=ECX;
131
      endcase
132 6 ultro
      case(state)  // EDX control
133 7 ultro
        `init       : EDX <= 32'b0;
134 6 ultro
        `sdv1       : EDX <= smlEAX;
135
        `div1       : EDX <=    EAX;
136 9 ultro
        `sdv3       : if (nbF==1'b0) EDX <= EDX - ECX; else EDX <= EDX;
137 6 ultro
        `sdv4       : if (EBX[31] == 1'b1) EDX <= ((~EDX) + 1); else EDX<=EDX;
138
        default     : if (dest==3'b010) EDX <= alu_out; else EDX<=EDX;
139
      endcase
140 5 ultro
      case(state)  // ESP control
141 13 ultro
        `init              : ESP <= 32'h0191fc;
142 12 ultro
        `call,`calla,`int1 : ESP <= ESP - 4'b0100;
143
        `ret2              : ESP <= ESP + 4'b0100;
144 5 ultro
       default: if (dest==3'b100) ESP <= alu_out; else ESP<=ESP;
145
      endcase
146
      if (dest==3'b101) EBP <= alu_out; else EBP<=EBP;  // EBP control 
147
      case(state)  // PC control
148 12 ultro
       `init        : PC<=32'h0001000;
149
       `int2        : PC<=32'h0;
150 5 ultro
       `jae2        : PC<=pc_jae;
151
       `jbe2        : PC<=pc_jbe;
152
       `ja2         : PC<=pc_ja ;
153
       `jb2         : PC<=pc_jb ;
154
       `jge2        : PC<=pc_jge;
155
       `jle2        : PC<=pc_jle;
156
       `jg2         : PC<=pc_jg ;
157
       `jl2         : PC<=pc_jl ;
158
       `je2         : PC<=pc_eq ;
159
       `jne2        : PC<=pc_neq;
160
       `jmp2,`call2 : PC<=pc_jp ;
161 8 ultro
       `calla2      : PC<=EBX;
162 5 ultro
       `ret2        : PC<=D     ;
163 6 ultro
       `mul,`mul2,`sml1,`sml2,`sml3,`sml4,`sdv1,`sdv2,`sdv3,`sdv4,`div1,
164 12 ultro
       `shift,`int1 : PC<=PC    ;
165
       `fetch       : if (nstate == `shift) PC<=PC;
166 7 ultro
                 else if (ID[15:8]==8'heb) PC <= pc_sh;
167
                 else if((ID[15:8]==8'h75) && (eqF==1'b0)) PC <= pc_sh;
168
                 else if((ID[15:8]==8'h74) && (eqF==1'b1)) PC <= pc_sh;
169
                 else PC<=incPC ;
170 12 ultro
       default      : PC<=incPC ;
171 5 ultro
      endcase
172
     end
173 2 ultro
// muxing for source selection, used in alu & moves
174
always@(src,EAX,ECX,EDX,EBX,ESP,EBP,D)
175
   case(src)
176
    3'b000 : regsrc = EAX;
177
    3'b001 : regsrc = ECX;
178
    3'b010 : regsrc = EDX;
179
    3'b100 : regsrc = ESP;
180
    3'b101 : regsrc = EBP;
181 7 ultro
    3'b110 : regsrc = 32'h04;
182 2 ultro
    3'b111 : regsrc = D;
183
    default: regsrc = EBX;
184
   endcase
185
// muxing for 2nd operand selection, used in alu only
186
always@(dest,EAX,ECX,EDX,EBX,ESP,EBP,D)
187
   case(dest)
188
    3'b000 : regdest = EAX;
189
    3'b001 : regdest = ECX;
190
    3'b010 : regdest = EDX;
191
    3'b100 : regdest = ESP;
192
    3'b101 : regdest = EBP;
193 7 ultro
    3'b110 : regdest = 32'h04;
194 2 ultro
    3'b111 : regdest = D  ;
195
    default: regdest = EBX;
196
   endcase
197
// alu
198 4 ultro
always@(state,regdest,regsrc,ID,cry,Zregsrc,Sregsrc,sft_out,adder_out,sub_out)
199
  if (state == `fetch )
200 2 ultro
  case (ID[15:10])
201 4 ultro
   6'b000000 : {ncry,alu_out} =             adder_out ;  // ADD , carry generation
202
   6'b000010 : {ncry,alu_out} = {cry,regdest | regsrc};  // OR
203
   6'b000100 : {ncry,alu_out} =             adder_out ;  // ADD , carry use
204
   6'b000110 : {ncry,alu_out} =               sub_out ;  // SUB , carry use
205
   6'b001000 : {ncry,alu_out} = {cry,regdest & regsrc};  // AND
206
   6'b001010 : {ncry,alu_out} =               sub_out ;  // SUB , carry generation
207
   6'b001100 : {ncry,alu_out} = {cry,regdest ^ regsrc};  // XOR
208
   6'b100010 : {ncry,alu_out} = {cry,          regsrc};  // MOVE
209
   6'b101101 : {ncry,alu_out} = {cry,         Zregsrc};  // MOVE
210
   6'b101111 : {ncry,alu_out} = {cry,         Sregsrc};  // MOVE
211
   default   : {ncry,alu_out} = {cry,regdest         };  // DO NOTHING
212 2 ultro
  endcase
213 5 ultro
  else if (state == `shift ) {ncry,alu_out} = {cry,sft_out           };
214 4 ultro
  else {ncry,alu_out} = {cry,regdest         };
215 2 ultro
// Main instruction decode
216 12 ultro
always @(ID,state,ECX,EBX_shtr,EAX,divF1,divF2,INTvalid)
217 2 ultro
 begin
218
   // One cycle instructions, operand selection
219 5 ultro
   if ((state == `fetch) || (state ==`shift))
220 10 ultro
     casex ({ID[15:12],ID[10:9],ID[7]})
221
      7'b10x0000  : begin RD=0;WR=1; src=ID[5:3]; dest= 3'b111; end  // store into ram (x89 x00)
222
      7'b100xx10  : begin RD=1;WR=0; src= 3'b111; dest=ID[5:3]; end  // load from ram  (x8b x00)
223
      7'b101xx10  : begin RD=0;WR=0; src= 3'b111; dest=ID[5:3]; end  // load bl with immediate
224
      7'b10xxx11  : begin RD=0;WR=0; src=ID[2:0]; dest=ID[5:3]; end  // reg2reg xfer   (x8b xC0)
225
      7'b00xxx11  : begin RD=0;WR=0; src=ID[2:0]; dest=ID[5:3]; end  // alu op
226
      default   : begin RD=0;WR=0; src=ID[5:3]; dest=ID[2:0]; end  // shift
227 2 ultro
     endcase
228
   else if (state==`ret)
229 10 ultro
        begin src = 3'b011; dest = 3'b100; RD=0; WR=0; end
230 6 ultro
   else if (state==`sdv3)
231 10 ultro
        begin src = 3'b001; dest = 3'b010; RD=0; WR=0; end
232
   else begin src = 3'b000; dest = 3'b000; RD=0; WR=0; end
233 2 ultro
   // instructions that require more than one cycle to execute
234 12 ultro
   if (state == `fetch)
235
    begin
236
     casex({INTvalid,ID})
237
     17'h1xxxx: nstate = `int1;
238
     17'h090e9: nstate = `jmp;
239
     17'h00f87: nstate = `ja;
240
     17'h00f86: nstate = `jbe;
241
     17'h00f83: nstate = `jae;
242
     17'h00f82: nstate = `jb;
243
     17'h00f8f: nstate = `jg;
244
     17'h00f8e: nstate = `jle;
245
     17'h00f8d: nstate = `jge;
246
     17'h00f8c: nstate = `jl;
247
     17'h00f85: nstate = `jne;
248
     17'h00f84: nstate = `je;
249
     17'h090bb: nstate = `imm;
250
     17'h08d9d: nstate = `lea;
251
     17'h08d5d: nstate = `leas;
252
     17'h090e8: nstate = `call;
253
     17'h090c3: nstate = `ret;
254
     17'h0c1xx: nstate = `shift;
255
     17'h0d3xx: nstate = `shift;
256
     17'h0f7e1: nstate = `mul;
257
     17'h0f7f9: nstate = `sdv1;
258
     17'h0f7f1: nstate = `div1;
259
     17'h0afc1: nstate = `sml1;
260
     17'h0ffd3: nstate = `calla;
261 2 ultro
     default : nstate = `fetch;
262
    endcase
263
    if (ID       == 16'h9066) nprefx = 1'b1; else nprefx = 1'b0;
264
    if (ID[15:8] ==  8'h39  ) cmpr   = 1'b1; else cmpr   = 1'b0;
265
   end
266
   else
267
   begin
268 3 ultro
        nprefx = 1'b0; cmpr   = 1'b0;
269 12 ultro
        if (state==`int1)  nstate = `int2;
270
   else if((state==`mul)&&!(ECX==32'b0)) nstate=`mul;
271 5 ultro
   else if((state==`mul)&& (ECX==32'b0)) nstate=`mul2;
272 3 ultro
   else if (state==`mul2)  nstate = `fetch;
273 5 ultro
   else if (state==`sml1)  nstate = `sml2;
274
   else if((state==`sml2)&&!(ECX==32'b0)) nstate=`sml2;
275
   else if((state==`sml2)&& (ECX==32'b0)) nstate=`sml3;
276 6 ultro
   else if (state==`div1)  nstate = `sdv2;
277
   else if (state==`sdv1)  nstate = `sdv2;
278
   else if((state==`sdv2) && (divF1 == 1'b0) ) nstate=`sdv2;
279
   else if((state==`sdv2) && (divF1 == 1'b1) ) nstate=`sdv3;
280
   else if((state==`sdv3) && (divF2 == 1'b0) ) nstate=`sdv3;
281
   else if((state==`sdv3) && (divF2 == 1'b1) ) nstate=`sdv4;
282 3 ultro
   else if (state==`jmp)   nstate = `jmp2;  else if (state==`jmp2)  nstate = `fetch;
283 2 ultro
   else if (state==`jne)   nstate = `jne2;  else if (state==`jne2)  nstate = `fetch;
284
   else if (state==`je )   nstate = `je2 ;  else if (state==`je2 )  nstate = `fetch;
285
   else if (state==`jge)   nstate = `jge2;  else if (state==`jge2)  nstate = `fetch;
286
   else if (state==`jg )   nstate = `jg2 ;  else if (state==`jg2 )  nstate = `fetch;
287
   else if (state==`jle)   nstate = `jle2;  else if (state==`jle2)  nstate = `fetch;
288
   else if (state==`jl )   nstate = `jl2 ;  else if (state==`jl2 )  nstate = `fetch;
289 5 ultro
   else if (state==`jae)   nstate = `jae2;  else if (state==`jae2)  nstate = `fetch;
290
   else if (state==`ja )   nstate = `ja2 ;  else if (state==`ja2 )  nstate = `fetch;
291
   else if (state==`jbe)   nstate = `jbe2;  else if (state==`jbe2)  nstate = `fetch;
292
   else if (state==`jb )   nstate = `jb2 ;  else if (state==`jb2 )  nstate = `fetch;
293 2 ultro
   else if (state==`imm)   nstate = `imm2;  else if (state==`imm2)  nstate = `fetch;
294
   else if (state==`lea)   nstate = `lea2;  else if (state==`lea2)  nstate = `fetch;
295
   else if (state==`call)  nstate = `call2; else if (state==`call2) nstate = `fetch;
296 8 ultro
   else if (state==`calla) nstate = `calla2;else if (state==`calla2)nstate = `fetch;
297 2 ultro
   else if (state==`ret)   nstate = `ret2;  else if (state==`ret2)  nstate = `fetch;
298 5 ultro
   else if((state==`shift)&&!(EBX_shtr==5'b0)) nstate=`shift;
299
   else if((state==`shift)&& (EBX_shtr==5'b0)) nstate=`shft2;
300 9 ultro
   else if (state==`shft2) nstate = `shft3;
301 2 ultro
   else                    nstate = `fetch;
302
   end
303
 end
304 12 ultro
assign INTvalid = INTreg & (WR | RD);
305 5 ultro
assign ssregsrc = regsrc;
306
assign ssregdest= regdest;
307 2 ultro
assign  IA      = PC                ;
308 12 ultro
assign  A       =((state == `call2)|(state == `calla2)|(state == `int2)) ?  ESP          : EBX      ;
309
assign  Q       =((state == `call2)|(state == `calla2)|(state == `int2)) ?  incPC        : regsrc   ;
310 7 ultro
assign  WEN     = (CE    ==   1'b0) ?  1'b1         :
311 10 ultro
                  (WR    ==   1'b1) ?  1'b0         :
312 8 ultro
                  (state == `call2) ?  1'b0         :
313 12 ultro
                  (state == `int2 ) ?  1'b0         :
314 8 ultro
                  (state == `calla2)?  1'b0         : 1'b1     ;
315 2 ultro
assign  Sregsrc =       ID[8]       ? { {16{regsrc[15]}} , regsrc[15:0] } :
316
                                      { {24{regsrc[7] }} , regsrc[7:0]  } ;
317
assign  Zregsrc =       ID[8]       ? {  16'b0           , regsrc[15:0] } :
318
                                      {  24'b0           , regsrc[7:0]  } ;
319 13 ultro
assign      BEN = (state == `fetch) ? { prefx   , ID[8]        } : 1'b1;
320
//assign      BEN =((state == `call2)|(state == `calla2)) ? 1'b1 : { prefx   , ID[8]        } ;
321 2 ultro
assign     neqF = (regsrc == regdest) ? 1'b1 : 1'b0;
322 8 ultro
assign      nbF = (regsrc  > regdest) ? 1'b1 : 1'b0;
323 10 ultro
assign      naF = ~(nlF | neqF );
324 8 ultro
assign      nlF = (ssregsrc  > ssregdest) ? 1'b1 : 1'b0;
325 10 ultro
assign      ngF = ~(nbF | neqF );
326 2 ultro
assign    incPC = PC + 3'b010;
327 5 ultro
assign   pc_jge = (eqF|gF) ? pc_jp : incPC;
328
assign   pc_jle = (eqF|lF) ? pc_jp : incPC;
329
assign   pc_jg  = (gF    ) ? pc_jp : incPC;
330
assign   pc_jl  = (lF    ) ? pc_jp : incPC;
331
assign   pc_jae = (eqF|aF) ? pc_jp : incPC;
332
assign   pc_jbe = (eqF|bF) ? pc_jp : incPC;
333
assign   pc_ja  = (aF    ) ? pc_jp : incPC;
334
assign   pc_jb  = (bF    ) ? pc_jp : incPC;
335
assign   pc_eq  = (eqF   ) ? pc_jp : incPC;
336
assign   pc_neq = (eqF   ) ? incPC : pc_jp;
337 2 ultro
assign   pc_jp  = incPC+{ID,EBX[15:0]};
338 7 ultro
assign   pc_sh  = incPC + { {24{ID[7]}} , ID[7:0] };
339 5 ultro
assign  sft_out = (src   == 3'b111) ? {regdest[31],regdest[31:1]} : //sar
340
                  (src   == 3'b101) ? {       1'b0,regdest[31:1]} : //shr
341
                                      {regdest[30:0],1'b0       } ; //shl
342 2 ultro
assign adder_out= nncry   + regsrc + regdest;
343
assign   sub_out= regdest - regsrc - nncry;
344 4 ultro
assign    nncry = (ID[12] ? cry : 1'b0);
345 5 ultro
assign EBX_shtr = EBX[4:0] - 1'b1;
346 6 ultro
assign   smlEAX = EAX[31] ? ((~EAX) + 1) : EAX;
347
assign   smlECX = ECX[31] ? ((~ECX) + 1) : ECX;
348 9 ultro
assign    divF1 = ({ECX[31:0],1'b0}  > {1'b0,EDX}) ? 1'b1 : 1'b0;
349 6 ultro
assign    divF2 = (EBX_shtr == 5'b00000) ? 1'b1 : 1'b0;
350 2 ultro
endmodule

powered by: WebSVN 2.1.0

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