1 |
6 |
root |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Module Name: nCore
|
4 |
|
|
// Author: STEFAN, Istvan
|
5 |
|
|
// Published under GPL
|
6 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
7 |
|
|
module nCore(IP, DP, In, data_out, data_in, clkin);
|
8 |
|
|
parameter inst_mvA=4'd0;//Move reg to a
|
9 |
|
|
parameter inst_coA=4'd1;//Move constant to a[3:0]
|
10 |
|
|
parameter inst_mvB=4'd2;//Move reg to b
|
11 |
|
|
parameter inst_coB=4'd3;//Move constant to b[3:0]
|
12 |
|
|
parameter inst_csB=4'd4;//b[7:4]<-b[3:0];b[3:0]<-constant
|
13 |
|
|
parameter inst_shl=4'd5;//Shift to left, a<reg,carry->flag,if zero->flag
|
14 |
|
|
parameter inst_shr=4'd6;//Shift to right a>>b->reg,carry->flag,if zero->flag
|
15 |
|
|
parameter inst_and=4'd7;//Aritmetical and a&b->reg,if zero->flag
|
16 |
|
|
parameter inst_orr=4'd8;//Aritmetical or a|b->reg,if zero->flag
|
17 |
|
|
parameter inst_xor=4'd9;//Aritmetical xor a^b->reg,if zero->flag
|
18 |
|
|
parameter inst_add=4'd10;//Unsigned add a+b->reg,carry->flag,if zero->flag
|
19 |
|
|
parameter inst_sub=4'd11;//Unsigned sub a-b->reg,carry->flag,if zero->flag
|
20 |
|
|
parameter inst_int=4'd12;
|
21 |
|
|
parameter inst_ire=4'd13;
|
22 |
|
|
parameter inst_Imv=4'd14;//Move IP to reg
|
23 |
|
|
parameter inst_jmp=4'd15;//Move reg to IP if a[0]
|
24 |
|
|
|
25 |
|
|
//buswidth constants
|
26 |
|
|
parameter dw=15;
|
27 |
|
|
//parameter maxaddrbits=10;
|
28 |
|
|
//parameter Dmaxaddrbits=10;
|
29 |
|
|
|
30 |
|
|
output [dw:0] IP;
|
31 |
|
|
output [dw:0] DP;
|
32 |
|
|
input [7:0] In;
|
33 |
|
|
output [dw:0] data_out;
|
34 |
|
|
input [dw:0] data_in;
|
35 |
|
|
input clkin;
|
36 |
|
|
|
37 |
|
|
//Instructions
|
38 |
|
|
wire [7:0] In;
|
39 |
|
|
//Sign of the clock
|
40 |
|
|
wire clk;
|
41 |
|
|
//Instruction pointer
|
42 |
|
|
reg [dw:0] IP=0;//init to 0
|
43 |
|
|
//Data pointer
|
44 |
|
|
wire [dw:0] DP;//init to 0
|
45 |
|
|
//Contact with the data memory
|
46 |
|
|
wire [dw:0] data_in;
|
47 |
|
|
wire [dw:0] data_out;
|
48 |
|
|
|
49 |
|
|
//Source registers
|
50 |
|
|
reg [dw:0] a=0;
|
51 |
|
|
reg [dw:0] b=0;
|
52 |
|
|
//General registers
|
53 |
|
|
reg [dw:0] regs [14:0];
|
54 |
|
|
reg [dw:0] mask;//Register for masking addresses
|
55 |
|
|
//Flag register
|
56 |
|
|
// reg [15:0] FLAG=0;//init to 0
|
57 |
|
|
wire [4:0] FLAG_new;
|
58 |
|
|
wire F_pre_add,F_pre_sub,F_pre_shl,F_pre_shr;
|
59 |
|
|
//Interrupt
|
60 |
|
|
reg int=1;//We start in interrupt state to allow setting the environement
|
61 |
|
|
//Wire of results
|
62 |
|
|
wire [dw:0] t;
|
63 |
|
|
//Temp reg of results
|
64 |
|
|
reg [dw:0] c;
|
65 |
|
|
//The wires of part results
|
66 |
|
|
wire [dw:0] w_add;
|
67 |
|
|
wire [dw:0] w_sub;
|
68 |
|
|
wire [dw:0] w_shl;//shift to left
|
69 |
|
|
wire [dw:0] w_shr;//shift to right
|
70 |
|
|
wire [dw:0] w_and;
|
71 |
|
|
wire [dw:0] w_orr;
|
72 |
|
|
wire [dw:0] w_xor;
|
73 |
|
|
wire [3:0] w_con;//load constant
|
74 |
|
|
//Begin of ALU
|
75 |
|
|
wire F_zero;
|
76 |
|
|
assign F_zero=(t==16'h0000);
|
77 |
|
|
//assign FLAG_new[0]=((In[7:4]==inst_and)||(In[7:4]==inst_orr)||
|
78 |
|
|
// (In[7:4]==inst_xor)||(In[7:4]==inst_and)||
|
79 |
|
|
// (In[7:4]==inst_sub)||(In[7:4]==inst_shl)||
|
80 |
|
|
// (In[7:4]==inst_shr))?F_zero:regs[13][0];////:FLAG[0];
|
81 |
|
|
assign FLAG_new[0]=((In[7:4]==inst_and)||(In[7:4]==inst_orr)||
|
82 |
|
|
(In[7:4]==inst_xor)||(In[7:4]==inst_and)||
|
83 |
|
|
(In[7:4]==inst_sub)||(In[7:4]==inst_shl)||
|
84 |
|
|
(In[7:4]==inst_shr))?F_zero:regs[13][0];//:FLAG[0];
|
85 |
|
|
|
86 |
|
|
assign {F_pre_add,w_add}=a+b;
|
87 |
|
|
assign {F_pre_sub,w_sub}=a-b;
|
88 |
|
|
assign {F_pre_shl,w_shl}=a<
|
89 |
|
|
assign {w_shr,F_pre_shr}=a>>b[3:0];
|
90 |
|
|
|
91 |
|
|
assign w_and=a&b;
|
92 |
|
|
assign w_orr=a|b;
|
93 |
|
|
assign w_xor=a^b;
|
94 |
|
|
assign w_con=In[3:0];
|
95 |
|
|
//End of ALU
|
96 |
|
|
|
97 |
|
|
//Instruction pointer
|
98 |
|
|
always @(negedge clk)
|
99 |
|
|
if ((In[7:4]==inst_jmp)&&(a[0]))
|
100 |
|
|
begin
|
101 |
|
|
if(int)//Using the whole address space is allowed only in interrupt
|
102 |
|
|
IP=c;
|
103 |
|
|
else
|
104 |
|
|
IP={regs[13][15:5],5'b11111}&c;//Masking address DP
|
105 |
|
|
// IP=regs[In[3:0]];
|
106 |
|
|
end
|
107 |
|
|
else if((In[7:4]==inst_int))
|
108 |
|
|
begin
|
109 |
|
|
IP=16;//begin of the code of the interrupt
|
110 |
|
|
int=1;
|
111 |
|
|
end
|
112 |
|
|
else if((In[7:4]==inst_ire))
|
113 |
|
|
begin
|
114 |
|
|
IP=regs[12];
|
115 |
|
|
int=0;
|
116 |
|
|
end
|
117 |
|
|
else
|
118 |
|
|
IP=IP+1;
|
119 |
|
|
|
120 |
|
|
//Data pointer
|
121 |
|
|
assign DP=regs[15];
|
122 |
|
|
|
123 |
|
|
//Contact with the data memory
|
124 |
|
|
assign data_out=regs[14];
|
125 |
|
|
|
126 |
|
|
//Evaluation of the instructions
|
127 |
|
|
/*0-2*/assign t=((In[7:4]==inst_mvA)||(In[7:4]==inst_mvB))&&(In[3:0]==14)?data_in:16'hzzzz;
|
128 |
|
|
/*0*/ assign t=(In[7:4]==inst_mvA)?regs[In[3:0]]:16'hzzzz;
|
129 |
|
|
/*1*/ assign t=(In[7:4]==inst_coA)?w_con:16'hzzzz;
|
130 |
|
|
/*2*/ assign t=(In[7:4]==inst_mvB)?regs[In[3:0]]:16'hzzzz;
|
131 |
|
|
/*3*/ assign t=(In[7:4]==inst_coB)?w_con:16'hzzzz;
|
132 |
|
|
/*4*/ assign t=(In[7:4]==inst_csB)?{b[11:4],w_con}:16'hzzzz;
|
133 |
|
|
/*5*/ assign t=(In[7:4]==inst_shl)?w_shl:16'hzzzz;
|
134 |
|
|
assign FLAG_new[3]=(In[7:4]==inst_shl)?F_pre_shl:regs[13][3];//FLAG[3];
|
135 |
|
|
/*6*/ assign t=(In[7:4]==inst_shr)?w_shr:16'hzzzz;
|
136 |
|
|
assign FLAG_new[4]=(In[7:4]==inst_shr)?F_pre_shr:regs[13][4];//FLAG[4];
|
137 |
|
|
/*7*/ assign t=(In[7:4]==inst_and)?w_and:16'hzzzz;
|
138 |
|
|
/*8*/ assign t=(In[7:4]==inst_orr)?w_orr:16'hzzzz;
|
139 |
|
|
/*9*/ assign t=(In[7:4]==inst_xor)?w_xor:16'hzzzz;
|
140 |
|
|
/*10*/assign t=(In[7:4]==inst_add)?w_add:16'hzzzz;
|
141 |
|
|
assign FLAG_new[1]=(In[7:4]==inst_add)?F_pre_add:regs[13][1];//FLAG[1];
|
142 |
|
|
/*11*/assign t=(In[7:4]==inst_sub)?w_sub:16'hzzzz;
|
143 |
|
|
assign FLAG_new[2]=(In[7:4]==inst_sub)?F_pre_sub:regs[13][2];//FLAG[2];
|
144 |
|
|
/*14*/ assign t=(In[7:4]==inst_Imv)?IP:16'hzzzz;
|
145 |
|
|
|
146 |
|
|
//Implementation of the registres
|
147 |
|
|
wire i_mvA;
|
148 |
|
|
wire i_mvB;
|
149 |
|
|
wire i_mvR;
|
150 |
|
|
assign i_mvA=((In[7:4]==inst_mvA)||(In[7:4]==inst_coA))&&clk;
|
151 |
|
|
assign i_mvB=((In[7:4]==inst_mvB)||(In[7:4]==inst_coB)||(In[7:4]==inst_csB))&&clk;
|
152 |
|
|
assign i_mvR=(
|
153 |
|
|
(In[7:4]==inst_and)||(In[7:4]==inst_orr)
|
154 |
|
|
||(In[7:4]==inst_xor)||(In[7:4]==inst_add)
|
155 |
|
|
||(In[7:4]==inst_shr)||(In[7:4]==inst_shl)
|
156 |
|
|
||(In[7:4]==inst_sub)||(In[7:4]==inst_Imv)||(In[7:4]==inst_int)
|
157 |
|
|
)&&clk;
|
158 |
|
|
|
159 |
|
|
//First source register
|
160 |
|
|
always @(negedge i_mvA)
|
161 |
|
|
a=c;
|
162 |
|
|
|
163 |
|
|
//Second source register
|
164 |
|
|
always @(negedge i_mvB)
|
165 |
|
|
b=c;
|
166 |
|
|
|
167 |
|
|
//Keep the result
|
168 |
|
|
always @(negedge clk)
|
169 |
|
|
c=t;
|
170 |
|
|
|
171 |
|
|
always @(posedge clk)
|
172 |
|
|
begin
|
173 |
|
|
FLAG=FLAG_new;
|
174 |
|
|
end
|
175 |
|
|
|
176 |
|
|
always @(negedge i_mvR)//TODO!!!
|
177 |
|
|
begin
|
178 |
|
|
if(int)
|
179 |
|
|
begin
|
180 |
|
|
if(In[3:0]==15)
|
181 |
|
|
mask=c;
|
182 |
|
|
else
|
183 |
|
|
regs[In[3:0]]=c;
|
184 |
|
|
end
|
185 |
|
|
else
|
186 |
|
|
begin
|
187 |
|
|
if(In[7:4]==inst_int)
|
188 |
|
|
regs[12]=IP;
|
189 |
|
|
else begin
|
190 |
|
|
if(In[3:0]<13)
|
191 |
|
|
regs[In[3:0]]=c;
|
192 |
|
|
else
|
193 |
|
|
if(In[3:0]==14)
|
194 |
|
|
regs[14]=mask&c;//Masking address DP
|
195 |
|
|
end
|
196 |
|
|
end
|
197 |
|
|
end
|
198 |
|
|
//mask:regs[15]
|
199 |
|
|
//DP:regs[14]
|
200 |
|
|
//data:regs[13]
|
201 |
|
|
//retA:regs[12]:address of the return from interrupt
|
202 |
|
|
BUFGP U1 (.I(clkin),.O(clk));
|
203 |
|
|
|
204 |
|
|
endmodule
|