1 |
2 |
ndumitrach |
//////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//
|
3 |
|
|
// This file is part of the Next186 project
|
4 |
|
|
// http://opencores.org/project,next186
|
5 |
|
|
//
|
6 |
|
|
// Filename: Next186_Regs.v
|
7 |
|
|
// Description: Part of the Next186 CPU project, registers module
|
8 |
|
|
// Version 1.0
|
9 |
|
|
// Creation date: 11Apr2011 - 07Jun2011
|
10 |
|
|
//
|
11 |
|
|
// Author: Nicolae Dumitrache
|
12 |
|
|
// e-mail: ndumitrache@opencores.org
|
13 |
|
|
//
|
14 |
|
|
/////////////////////////////////////////////////////////////////////////////////
|
15 |
|
|
//
|
16 |
|
|
// Copyright (C) 2011 Nicolae Dumitrache
|
17 |
|
|
//
|
18 |
|
|
// This source file may be used and distributed without
|
19 |
|
|
// restriction provided that this copyright statement is not
|
20 |
|
|
// removed from the file and that any derivative work contains
|
21 |
|
|
// the original copyright notice and the associated disclaimer.
|
22 |
|
|
//
|
23 |
|
|
// This source file is free software; you can redistribute it
|
24 |
|
|
// and/or modify it under the terms of the GNU Lesser General
|
25 |
|
|
// Public License as published by the Free Software Foundation;
|
26 |
|
|
// either version 2.1 of the License, or (at your option) any
|
27 |
|
|
// later version.
|
28 |
|
|
//
|
29 |
|
|
// This source is distributed in the hope that it will be
|
30 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied
|
31 |
|
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
32 |
|
|
// PURPOSE. See the GNU Lesser General Public License for more
|
33 |
|
|
// details.
|
34 |
|
|
//
|
35 |
|
|
// You should have received a copy of the GNU Lesser General
|
36 |
|
|
// Public License along with this source; if not, download it
|
37 |
|
|
// from http://www.opencores.org/lgpl.shtml
|
38 |
|
|
//
|
39 |
|
|
///////////////////////////////////////////////////////////////////////////////////
|
40 |
|
|
`timescale 1ns / 1ps
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
module Next186_Regs(
|
44 |
|
|
input [2:0]RASEL,
|
45 |
|
|
input [2:0]RBSEL,
|
46 |
|
|
input BASEL,
|
47 |
|
|
input [1:0]BBSEL,
|
48 |
|
|
input [1:0]RSSEL,
|
49 |
|
|
input [15:0]DIN,
|
50 |
|
|
input [15:0]ALUOUT,
|
51 |
|
|
input [15:0]ADDR16,
|
52 |
|
|
input [15:0]DIMM,
|
53 |
|
|
input [4:0]WE, // 4=flags, 3=TMP16, 2=RSSEL, 1=RASEL_HI, 0=RASEL_LO
|
54 |
|
|
input IFETCH,
|
55 |
|
|
input [15:0]FIN,
|
56 |
|
|
input [1:0]DISEL,
|
57 |
|
|
input [15:0]IPIN,
|
58 |
|
|
input WORD,
|
59 |
|
|
input INCSP,
|
60 |
|
|
input DECCX,
|
61 |
|
|
input DIVOP,
|
62 |
|
|
input DIVEND,
|
63 |
|
|
input DIVC,
|
64 |
|
|
input DIVSGN,
|
65 |
|
|
output [1:0]CXZ,
|
66 |
|
|
output [15:0]FOUT,
|
67 |
|
|
output [15:0]RA,
|
68 |
|
|
output [15:0]RB,
|
69 |
|
|
output reg [15:0]TMP16,
|
70 |
|
|
output reg [15:0]SP,
|
71 |
|
|
output reg [15:0]IP,
|
72 |
|
|
output reg [15:0]AX,
|
73 |
|
|
output reg [15:0]BX,
|
74 |
|
|
output reg [15:0]BP,
|
75 |
|
|
output reg [15:0]SI,
|
76 |
|
|
output reg [15:0]DI,
|
77 |
|
|
output [15:0]RS,
|
78 |
|
|
output [15:0]CS,
|
79 |
|
|
output reg [15:0]DX,
|
80 |
|
|
output DIVEXC,
|
81 |
|
|
input CLK,
|
82 |
|
|
input CLKEN
|
83 |
|
|
);
|
84 |
|
|
|
85 |
|
|
reg [15:0]CX;
|
86 |
|
|
reg [15:0]SREG[3:0];
|
87 |
|
|
reg [8:0]FLG;
|
88 |
|
|
reg [15:0]REG_ASEL;
|
89 |
|
|
reg [15:0]REG_BSEL;
|
90 |
|
|
wire [15:0]RW = DISEL[0] ? ALUOUT : ADDR16; // x1=ALU, 10=ADDR, 00=DIN
|
91 |
|
|
wire [2:0]ASEL = {WORD & RASEL[2], RASEL[1:0]};
|
92 |
|
|
wire [2:0]BSEL = {WORD & RBSEL[2], RBSEL[1:0]};
|
93 |
|
|
wire [7:0]RWHI = WORD || &WE[1:0] ? RW[15:8] : RW[7:0];
|
94 |
|
|
wire [8:0]RWDL = {DIVOP && ~DIVC ? DX[7:0] : RW[7:0], AX[15]};
|
95 |
|
|
wire [8:0]RWDH = {DIVOP && ~DIVC ? DX[15:7] : {RWHI, RW[7]}};
|
96 |
|
|
wire [8:0]RWAH = {DIVOP && ~DIVC ? AX[15:8] : RWHI, AX[7]};
|
97 |
|
|
assign DIVEXC = WORD ? RWDH[8] : RWAH[8];
|
98 |
|
|
|
99 |
|
|
wire FASTDIN = ~|DISEL;
|
100 |
|
|
wire [15:0]FDRW = FASTDIN ? DIN : RW;
|
101 |
|
|
wire [7:0]FASTDINH = WORD || &WE[1:0] ? DIN[15:8] : DIN[7:0]; // fast data path for AH/DH (tweak for speed)
|
102 |
|
|
wire [15:0]CXM1 = CX + 16'hffff;
|
103 |
|
|
|
104 |
|
|
assign FOUT = {4'b0000, FLG[8:3], 1'b0, FLG[2], 1'b0, FLG[1], 1'b1, FLG[0]};
|
105 |
|
|
assign CS = SREG[1];
|
106 |
|
|
assign CXZ = {|CX[15:1], CX[0]};
|
107 |
|
|
|
108 |
|
|
wire [15:0]RA1 = {REG_ASEL[15:8], WORD | !RASEL[2] ? REG_ASEL[7:0] : REG_ASEL[15:8]};
|
109 |
|
|
assign RA = BASEL ? RA1 : TMP16;
|
110 |
|
|
assign RB = BBSEL[1] ? BBSEL[0] ? SREG[BSEL[1:0]] : DIMM : BBSEL[0] ? {REG_BSEL[15:8], WORD | !RBSEL[2] ? REG_BSEL[7:0] : REG_BSEL[15:8]} : TMP16;
|
111 |
|
|
assign RS = SREG[RSSEL];
|
112 |
|
|
|
113 |
|
|
always @* begin
|
114 |
|
|
case(ASEL)
|
115 |
|
|
0: REG_ASEL = AX;
|
116 |
|
|
1: REG_ASEL = CX;
|
117 |
|
|
2: REG_ASEL = DX;
|
118 |
|
|
3: REG_ASEL = BX;
|
119 |
|
|
4: REG_ASEL = SP;
|
120 |
|
|
5: REG_ASEL = BP;
|
121 |
|
|
6: REG_ASEL = SI;
|
122 |
|
|
7: REG_ASEL = DI;
|
123 |
|
|
endcase
|
124 |
|
|
case(BSEL)
|
125 |
|
|
0: REG_BSEL = AX;
|
126 |
|
|
1: REG_BSEL = CX;
|
127 |
|
|
2: REG_BSEL = DX;
|
128 |
|
|
3: REG_BSEL = BX;
|
129 |
|
|
4: REG_BSEL = SP;
|
130 |
|
|
5: REG_BSEL = BP;
|
131 |
|
|
6: REG_BSEL = SI;
|
132 |
|
|
7: REG_BSEL = DI;
|
133 |
|
|
endcase
|
134 |
|
|
end
|
135 |
20 |
ndumitrach |
|
136 |
2 |
ndumitrach |
always @(posedge CLK)
|
137 |
|
|
if(CLKEN) begin
|
138 |
|
|
if(WE[0] && ASEL == 0) AX[7:0] <= FDRW[7:0];
|
139 |
|
|
else if(DIVOP) AX[7:0] <= {AX[6:0], DIVC ^ DIVSGN};
|
140 |
|
|
|
141 |
|
|
if(WE[1] && ASEL == 0) AX[15:8] <= FASTDIN ? FASTDINH : (DIVOP && ~DIVEND ? RWAH[7:0] : RWAH[8:1]);
|
142 |
|
|
else if(DIVOP) AX[15:8] <= AX[14:7];
|
143 |
|
|
|
144 |
|
|
if(WE[0] && ASEL == 1) CX[7:0] <= FDRW[7:0];
|
145 |
|
|
else if(DECCX) CX[7:0] <= CXM1[7:0];
|
146 |
|
|
|
147 |
|
|
if(WE[1] && ASEL == 1) CX[15:8] <= FASTDIN ? FASTDINH : RWHI;
|
148 |
|
|
else if(DECCX) CX[15:8] <= CXM1[15:8];
|
149 |
|
|
|
150 |
|
|
if(WE[0] && ASEL == 2) DX[7:0] <= FASTDIN ? DIN[7:0] : (DIVOP && ~DIVEND ? RWDL[7:0] : RWDL[8:1]);
|
151 |
|
|
if(WE[1] && ASEL == 2) DX[15:8] <= FASTDIN ? FASTDINH : (DIVOP && ~DIVEND ? RWDH[7:0] : RWDH[8:1]);
|
152 |
|
|
|
153 |
|
|
if(WE[0] && ASEL == 3) BX[7:0] <= FDRW[7:0];
|
154 |
|
|
if(WE[1] && ASEL == 3) BX[15:8] <= FASTDIN ? FASTDINH : RWHI;
|
155 |
|
|
|
156 |
|
|
if(WE[0] && ASEL == 4) SP <= FDRW;
|
157 |
|
|
else if(INCSP) SP <= ADDR16;
|
158 |
|
|
|
159 |
|
|
if(WE[0] && ASEL == 5) BP <= FDRW;
|
160 |
|
|
if(WE[0] && ASEL == 6) SI <= FDRW;
|
161 |
|
|
if(WE[0] && ASEL == 7) DI <= FDRW;
|
162 |
|
|
|
163 |
|
|
if(WE[2])
|
164 |
|
|
case(RASEL[1:0])
|
165 |
|
|
0: SREG[0] <= FDRW;
|
166 |
|
|
1: SREG[1] <= FDRW;
|
167 |
|
|
2: SREG[2] <= FDRW;
|
168 |
|
|
3: SREG[3] <= FDRW;
|
169 |
|
|
endcase
|
170 |
|
|
|
171 |
|
|
if(WE[3]) TMP16 <= |WE[1:0] ? (&DISEL[1:0] ? DIN : ADDR16) : FDRW; // TMP16
|
172 |
|
|
else TMP16 <= RA; // XCHG, MUL
|
173 |
|
|
|
174 |
|
|
if(WE[4]) FLG <= {FIN[11:6], FIN[4], FIN[2], FIN[0]}; // FLAGS
|
175 |
|
|
|
176 |
|
|
if(IFETCH) IP <= IPIN; // IP
|
177 |
|
|
end
|
178 |
|
|
|
179 |
|
|
endmodule
|