Laboratory Exercise 10 An Enhanced Processor
Digital Logic Lab Exercises Laboratory Exercise 10 An Enhanced Processor
下面是我做这个练习时写的资料。Instruction Set
Instruction |
Operation |
Function performed |
16bit code |
000 |
nop |
null operation |
000,000,000,000000 |
001 |
mv Rx,Ry |
Rx←[Ry] |
001,XXX,YYY,000000 |
010 |
mvi Rx,#D |
Rx←D |
010,XXX,000,000000 |
011 |
add Rx,Ry |
Rx←[Rx]+[Ry] |
011,XXX,YYY,000000 |
100 |
sub Rx,Ry |
Rx←[Rx]-[Ry] |
100,XXX,YYY,000000 |
101 |
ld Rx,[Ry] |
Rx←[[Ry]] |
101,XXX,YYY,000000 |
110 |
st Rx,[Ry] |
[Ry]←[Rx] |
110,XXX,YYY,000000 |
111 |
mvnz Rx,Ry |
if G!=0, Rx←[Ry] |
111,XXX,YYY,000000 |
MicroCtrl
|
|
T0 |
T1 |
T2 |
T3 |
nop |
I0 |
incr_PC, ADDRin IRin |
Done, ADDRin |
|
|
mv |
I1 |
Ryout , Rxin,Done, ADDRin if is_PC ADDRout Endif |
|
|
|
mvi |
I2 |
incr_PC ,ADDRin |
DINout,Rxin,ADDRin,Done if is_PC ADDRout Endif |
|
|
add |
I3 |
Rxout , Ain, |
Ryout , Gin, |
Gout,Rxin,,ADDRin,Done if is_PC ADDRout Endif |
|
sub |
I4 |
Rxout , Ain, |
Ryout,Gin,AddSub |
Gout,Rxin,,ADDRin,Done if is_PC ADDRout Endif |
|
ld |
I5 |
Ryout,ADDRout,ADDRin, |
DINout,Rxin,ADDRin,Done if is_PC ADDRout Endif |
|
|
st |
I6 |
Ryout,ADDRout,ADDRin, |
Rxout,DOUTin W_D, |
ADDRin,Done |
|
mvnz |
I7 |
if Z==0 Ryout , Rxin,Endif if Ryout==PC, ADDRin ADDRout Endif Done |
|
|
|
ctrl_fsm[27:0] |
||||||||
|
31 |
30 |
29 |
28 |
27 |
26 |
25-18 |
17 |
16 |
|
|
|
|
|
ADDRout, |
IRin |
R0out-R7out |
Gout |
DINout |
|
15 |
14-7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
incr_PC |
R0in-R7in |
Ain |
Gin |
AddSub |
ADDRin |
DOUTin |
W_D |
Done |
测试全部的指令。
Instruction Test
assemblers |
Hex code |
binary code |
||
00 |
mvi |
R2,#1 |
0x4800 0x0001 |
010,010,000,0000000 |
02 |
nop |
0x0000 |
||
03 |
mvi |
R4,#2 |
0x5000 0x02 |
010,100,000,0000000 |
05 |
mvi |
R7,#H1C |
0x5C00 0x1C |
010,111,000,0000000 |
07 |
mvi |
R1,#H42 |
0x4400 0x42 |
010,001,000,0000000 |
09 |
mvi |
R0,#H4321 |
0x4000 0x4321 |
010,000,000,0000000 |
0B |
add |
R6,R2 |
0x7900 |
011,110,010,0000000 |
0C |
mv |
R5,R7 |
0x3780 |
001,101,111,0000000 |
0D |
sub |
R4,R2 |
0x9100 |
100,100,010,0000000 |
0E |
mvnz |
R7,R5 |
0xFE80 |
111,111,101,0000000 |
0F |
mvi |
R3,#40 |
0x4C00 0x0040 |
010,011,000,0000000 |
11 |
ld |
R6,[R3] |
0xB980 |
101,110,011,0000000 |
12 |
add |
R3,R2 |
0x6D00 |
011,011,010,0000000 |
13 |
nop |
|||
14 |
st |
R6,[R3] |
0xD980 |
110,110,011,0000000 |
15 |
ld |
R6,[R1] |
0xB880 |
101,110,001,0000000 |
16 |
st |
R0,[R6] |
0xC300 |
110,000,110,0000000 |
17 |
mvi |
R6,#4 |
0x5800 0x04 |
010,110,000,0000000 |
19 |
ld |
R7,[R3] |
0xBD80 |
101,111,011,0000000 |
1A |
mv |
R7,R4 |
0x3E00 |
001,111,100,0000000 |
1B |
sub |
R7,R6 |
0x9F00 |
100,111,110,0000000 |
1C |
mvi |
R7,#7 |
0x5C00 0x07 |
010,111,000,0000000 |
[0x40] = 0x001B [0x42]=0x1000
LED Tester
|
assemblers |
Hex code |
binary code |
|
0 |
mvi |
R0,#D1 |
0x4000 0x0001 |
010,000,000,0000000 |
2 |
mvi |
R3,#D0 |
0x4C00 0x0000 |
010,011,000,0000000 |
4 |
mvi |
R1,#D2 |
0x4400 0x0002 |
010,001,000,0000000 |
6 |
mv |
R4,R7 |
0x3380 |
001,100,111,0000000 |
7 |
mvi |
R2,# 3 |
0x4800 0x0003 |
010,010,000,0000000 |
9 |
mv |
R5,R7 |
0x3780 |
001,101,111,0000000 |
A |
sub |
R2,R0 |
0x8800 |
100,010,000,0000000 |
B |
mvnz |
R7,R5 |
0xFE80 |
111,111,101,0000000 |
C |
sub |
R1,R0 |
0x8400 |
100,001,000,0000000 |
D |
mvnz |
R7,R4 |
0xFE00 |
111,111,100,0000000 |
E |
add |
R3,R0 |
0x6C00 |
011,011,000,0000000 |
10 |
mvi |
R1,#H1000 |
0x4400 0x1000 |
010,001,000,0000000 |
11 |
st |
R3,[R1] |
0xCC80 |
110,011,001,0000000 |
12 |
mvi |
R7,#H4 |
0x5C00 0x0004 |
010,111,000,0000000 |
13 |
|
|
|
|
下面为CORE.V的全部代码。
1 module core(DIN, Resetn, Clock, Run, Done, DOUT,ADDR,W);
2
3 //declare inputs & outputs
4 input [15:0] DIN;
5 input Resetn, Clock, Run;
6 output Done;
7 output [15:0]DOUT,ADDR;
8 output W;
9
10 parameter T0 = 2'b00, T1 = 2'b01, T2 = 2'b10, T3 = 2'b11;
11
12 //declare variables
13 wire ADDRout; //General reg to index address
14 wire IRin; //Instruction In signal
15 wire Gout;
16 wire DINout; //Date out signal
17 wire incr_PC; //PC Increment signal
18 wire Ain,Gin; //Accumulator and Gain in signal
19 wire addSub; //Add or sub signal to ALU
20 wire ADDRin; //Adderss reg in signal
21 wire DOUTin; //Dataout in signal
22 wire W_D; //Write output in signal
23
24
25 reg [27:0]ctrl_fsm; //All fsm control signals
26 reg [1:0]Tstep_D,Tstep_Q; //Time step
27 reg internal_run;
28 //declare wires
29 wire [7:0]Rout;
30 wire [7:0]Rin; //R0-R7 In signal
31 wire [15:0]BusWires;
32 wire [15:0]alu_out;
33 wire [2:0]I;
34 wire [7:0]Xreg;
35 wire [7:0]Yreg;
36 wire [15:0]R0,R1,R2,R3,R4,R5,R6,R7,A,G;
37 wire [8:0]IR;
38 wire [9:0]ctrl_fsm_mux_signal;
39
40 wire [15:0]mux_to_Addr;
41 wire Z;
42 wire is_PC;
43
44 parameter f_ADDRout27= 1'b1;
45 parameter f_IRin26= 1'b1;
46 parameter f_Gout17 = 1'b1;
47 parameter f_DINout16= 1'b1;
48 parameter f_incr_PC15= 1'b1;
49 parameter f_Ain6= 1'b1;
50 parameter f_Gin5= 1'b1;
51 parameter f_AddSub4= 1'b1;
52 parameter f_ADDRin3= 1'b1;
53 parameter f_DOUTin2= 1'b1;
54 parameter f_W_D1= 1'b1;
55 parameter f_DONE0= 1'b1; //Instraction complete
56
57 assign Z = !(|G);
58
59 assign ADDRout = ctrl_fsm[27];
60 assign IRin = ctrl_fsm[26]; //if not running we do not want new instraction is in.
61 assign Rout = ctrl_fsm[25:18];
62 assign Gout = ctrl_fsm[17];
63 assign DINout = ctrl_fsm[16];
64 assign incr_PC=ctrl_fsm[15];
65 assign Rin = ctrl_fsm[14:7];
66 assign Ain=ctrl_fsm[6];
67 assign Gin=ctrl_fsm[5];
68 assign addSub=ctrl_fsm[4];
69 assign ADDRin=ctrl_fsm[3];
70 assign DOUTin=ctrl_fsm[2];
71 assign W_D = ctrl_fsm[1];
72 assign Done = ctrl_fsm[0];
73
74 assign is_PC = (Xreg==8'b0000_0001);
75
76 assign ctrl_fsm_mux_signal = {DINout,Gout,Rout};
77 //instantiate General and Special registers
78 regn reg_0 (BusWires, Rin[7], Clock, R0, Resetn);
79 regn reg_1 (BusWires, Rin[6], Clock, R1, Resetn);
80 regn reg_2 (BusWires, Rin[5], Clock, R2, Resetn);
81 regn reg_3 (BusWires, Rin[4], Clock, R3, Resetn);
82 regn reg_4 (BusWires, Rin[3], Clock, R4, Resetn);
83 regn reg_5 (BusWires, Rin[2], Clock, R5, Resetn);
84 regn reg_6 (BusWires, Rin[1], Clock, R6, Resetn);
85 regne reg_7 (BusWires, Rin[0], Clock, R7, Resetn,incr_PC);
86 regn reg_A (BusWires, Ain, Clock, A, Resetn);
87 regn reg_G (alu_out, Gin, Clock, G, Resetn);
88 regn reg_addr (mux_to_Addr, ADDRin, Clock, ADDR, Resetn);
89 regn reg_dout (BusWires, DOUTin, Clock, DOUT, Resetn);
90 //Write signal reg
91 regn#(1) reg_w (W_D, 1'b1, Clock, W, Resetn);
92
93 regn#(9) reg_IR (DIN[15:7], IRin, Clock, IR, Resetn);
94
95 //General Reg Selection
96 dec3to8 decX (IR[5:3], 1'b1, Xreg);
97 dec3to8 decY (IR[2:0], 1'b1, Yreg);
98
99 //
100 Mux2to1 muxpc(ADDRout,BusWires,R7,mux_to_Addr);
101 Mux10to1 muxfsm(ctrl_fsm_mux_signal, DIN, R0, R1, R2, R3, R4, R5, R6, R7, G,BusWires);
102
103 //instantiate adder/subtracter unit
104 ALUn alu(addSub,A,BusWires,alu_out);
105
106 // Load Instruction
107 assign I = IR[8:6];
108
109
110 always @(posedge Clock)
111 internal_run <= Run;
112
113 // Control FSM flip-flops
114 always @(posedge Clock, negedge Resetn)
115 if (!Resetn)
116 Tstep_Q <= T0;
117 else
118 Tstep_Q <= Tstep_D;
119
120 // Control FSM state table
121 always @(Tstep_Q, internal_run, Done)
122 begin
123 case (Tstep_Q)
124 T0:begin if(!internal_run) Tstep_D = T0;else Tstep_D = T1;end// data is loaded into IR in this time step
125 T1:begin if(Done) Tstep_D = T0;else Tstep_D = T2;end
126 T2:begin if(Done) Tstep_D = T0;else Tstep_D = T3;end
127 T3:Tstep_D = T0;
128 endcase
129 end
130
131 // Control FSM outputs
132 always @(Tstep_Q or I or Xreg or Yreg or Z or internal_run,is_PC)
133 begin
134 //specify initial values
135 case (Tstep_Q)
136 T0: // store DIN in IR in time step 0
137 if(internal_run)
138 ctrl_fsm = {1'b0,f_IRin26,{10{1'b0}},f_incr_PC15,{11{1'b0}},f_ADDRin3,3'b0};
139 else
140 ctrl_fsm = 0;
141 T1: //define signals in time step 1
142 begin
143 case (I)
144 //mv RX,RY
145 3'b001:ctrl_fsm = {f_ADDRout27&is_PC,1'b0,Yreg,{3{1'b0}},Xreg,3'b0,f_ADDRin3,2'b0,f_DONE0};
146 //mvi Rx, #D
147 3'b010:ctrl_fsm = {f_ADDRout27&is_PC,1'b0,8'h01,{2{1'b0}},f_incr_PC15,{11{1'b0}},f_ADDRin3,{3{1'b0}}};
148 3'b011,3'b100:ctrl_fsm = {2'b0,Xreg,11'b0,f_Ain6,{6{1'b0}}};
149 3'b101,3'b110:ctrl_fsm = {f_ADDRout27,1'b0,Yreg,1'b0,13'b0,f_ADDRin3,3'b0};
150 3'b111:
151 begin
152 if(!Z)
153 ctrl_fsm = {f_ADDRout27&is_PC,1'b0,Yreg,{3{1'b0}},Xreg,3'b0,f_ADDRin3,2'b0,f_DONE0};
154 else
155 ctrl_fsm = {{24{1'b0}},f_ADDRin3,2'b0,f_DONE0};
156 end
157 default:ctrl_fsm = {{24{1'b0}},f_ADDRin3,2'b0,f_DONE0};
158 endcase
159 end
160 T2: //define signals in time step 2
161 begin
162 case (I)
163 3'b010:ctrl_fsm = {f_ADDRout27&is_PC,1'b0,{9{1'b0}},f_DINout16,1'b0,Xreg,3'b0,f_ADDRin3,2'b0,f_DONE0};
164 3'b011:ctrl_fsm = {2'b0,Yreg,{12{1'b0}},f_Gin5,{5{1'b0}}};
165 3'b100:ctrl_fsm = {2'b0,Yreg,{12{1'b0}},f_Gin5,f_AddSub4,{4{1'b0}}};
166 3'b101:ctrl_fsm = {f_ADDRout27&is_PC,10'b0,f_DINout16,1'b0,Xreg,3'b0,f_ADDRin3,2'b0,f_DONE0};
167 3'b110:ctrl_fsm = {2'b0,Xreg,14'b0,1'b0,f_DOUTin2,f_W_D1,1'b0};
168 default:ctrl_fsm = 0;
169 endcase
170 end
171 T3: //define signals in time step 3
172 begin
173 case (I)
174 3'b011,3'b100:ctrl_fsm = {f_ADDRout27&is_PC,9'b0,f_Gout17,{2{1'b0}},Xreg,3'b0,f_ADDRin3,2'b0,f_DONE0};
175 3'b110:ctrl_fsm = {24'b0,f_ADDRin3,2'b0,f_DONE0};
176 default:ctrl_fsm = 0;
177 endcase
178 end
179 endcase
180 end
181 endmodule
分段
1 ///////////////////////////////////////
2 module regn(R, Rin, Clock, Q,rstn);
3 parameter n = 16;
4 input [n-1:0] R;
5 input Rin, Clock,rstn;
6 output [n-1:0] Q;
7 reg [n-1:0] Q;
8
9 always @(posedge Clock or negedge rstn)
10 if (!rstn)
11 Q <= 0;
12 else if (Rin)
13 Q <= R;
14
15 endmodule
1 ////////////////////////////////////
2 module regne(R, Rin, Clock, Q,rstn, inc);
3 parameter n = 16;
4 input [n-1:0] R;
5 input Rin, Clock,rstn, inc;
6 output [n-1:0] Q;
7 reg [n-1:0] Q;
8
9 always @(posedge Clock or negedge rstn)
10 begin
11 if (!rstn)
12 Q <= 0;
13 else if (Rin)
14 Q <= R;
15 else if(inc)
16 Q <= Q + 1'b1;
17 end
18 endmodule
1 //////////////////////////////////////////
2 module dec3to8(W, En, Y);
3
4 input [2:0] W;
5 input En;
6 output [0:7] Y;
7 reg [0:7] Y;
8
9 always @(W or En)
10 begin
11 if (En == 1)
12 case (W)
13 3'b000: Y = 8'b10000000;
14 3'b001: Y = 8'b01000000;
15 3'b010: Y = 8'b00100000;
16 3'b011: Y = 8'b00010000;
17 3'b100: Y = 8'b00001000;
18 3'b101: Y = 8'b00000100;
19 3'b110: Y = 8'b00000010;
20 3'b111: Y = 8'b00000001;
21 endcase
22 else
23 Y = 8'b00000000;
24 end
25 endmodule
1 ////////////////////////////////////
2 module Mux2to1(Select,A,B,Out);
3 input [15:0]A,B;
4 input Select;
5 output [15:0]Out;
6 reg [15:0]Out;
7
8 always@(Select or A or B)
9 begin
10 case (Select)
11 1'b1:Out = A;
12 default:Out = B;
13 endcase
14 end
15
16 endmodule
1 ////////////////////////////////////
2 module Mux10to1(Select, DIN, R0, R1, R2, R3, R4, R5, R6, R7, G,BusWires);
3 input [9:0] Select;
4 input [15:0] DIN,R0,R1,R2,R3,R4,R5,R6,R7,G;
5 output [15:0]BusWires;
6 reg [15:0]BusWires;
7
8 always @(Select or DIN or R0 or R1 or R2 or R3 or R4 or R5 or R6 or R7 or G)
9 begin
10 case (Select)
11 10'b10_0000_0000:BusWires = DIN;
12 10'b01_0000_0000:BusWires = G;
13 10'b00_1000_0000:BusWires = R0;
14 10'b00_0100_0000:BusWires = R1;
15 10'b00_0010_0000:BusWires = R2;
16 10'b00_0001_0000:BusWires = R3;
17 10'b00_0000_1000:BusWires = R4;
18 10'b00_0000_0100:BusWires = R5;
19 10'b00_0000_0010:BusWires = R6;
20 10'b00_0000_0001:BusWires = R7;
21 default:BusWires = 16'h55AA;
22 endcase
23 end
24 endmodule
1 ///////////////////////////////////////
2 module ALUn(M,A,B,Result);
3 parameter n = 16;
4 input [n-1:0] A,B;
5 input M;
6 output [n-1:0] Result;
7
8 Adder16 adder(M,A,B,1'b0,,,Result);
9
10 endmodule