1 |
5 |
sssayeekum |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Company:
|
4 |
|
|
// Engineer:
|
5 |
|
|
//
|
6 |
|
|
// Create Date: 17:00:45 08/26/2021
|
7 |
|
|
// Design Name:
|
8 |
|
|
// Module Name: MCPU8_1
|
9 |
|
|
// Project Name:
|
10 |
|
|
// Target Devices:
|
11 |
|
|
// Tool versions:
|
12 |
|
|
// Description:
|
13 |
|
|
//
|
14 |
|
|
// Dependencies:
|
15 |
|
|
//
|
16 |
|
|
// Revision:
|
17 |
|
|
// Revision 0.01 - File Created
|
18 |
|
|
// Additional Comments:
|
19 |
|
|
//
|
20 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
21 |
|
|
// Whenever a Control ROM location is assigned two different values , the latest value[i.e. current value] will be taken into consideration
|
22 |
|
|
// For example :
|
23 |
|
|
// CR[14] <= 17'b00111000011011001; // SU signal activated and Preset Counter Incremented
|
24 |
|
|
// CR[14] <= 17'b00111000001010001; // NOP instruction.
|
25 |
|
|
// In the above case NOP instruction will be executed.
|
26 |
|
|
// Assign a bus output of one device to input of multiple devices. This is allowed in Xilinx ISE 14.7 Webpack. Assign multiple outputs to a bus is not allowed. It is called bus driver overload
|
27 |
|
|
//
|
28 |
|
|
module MCPU8_1(input clk , input rst , output [4:0] PC_OUT , output [4:0] MAR_OUT , output [3:0] IR_OUT1 , output [4:0] IR_OUT2 , output[8:0] DATA_OUT1 , output[4:0] ADDR_OUT1 , output [4:0] COUNT_OUT , output [8:0] ACCUMULATOR_OUT , output [8:0] DATA_OUTPUT , output [8:0] B_REG , output [8:0] ALU_OUT , output [8:0] OR_out , output [16:0] CW, output EP , output CP , output LM , output CE ,output LI , output EI , output CS , output LOAD , output CLR , output INC , output LA , output EA , output LB , output SU , output AD , output EU , output LO);
|
29 |
|
|
wire [4:0] MAR_OUT_w , IR_OUT_2_w , MAR_IN_w , MUX_IN;
|
30 |
|
|
wire [3:0] IR_OUT_1_w;
|
31 |
|
|
wire [16:0] CW_w;
|
32 |
|
|
wire [8:0] DATA_IN_w;
|
33 |
|
|
wire[4:0] bus_5;
|
34 |
|
|
wire [4:0] bus_5_1;
|
35 |
|
|
wire [8:0] bus_9 , bus_9_1 , bus_9_2 , ACC_IN_w;
|
36 |
|
|
wire [8:0] ALU_A_w;
|
37 |
|
|
wire [8:0] ALU_B_w;
|
38 |
|
|
wire EP_w , CP_w , CS_w , CE_w , LOAD_w , LI_w , LM_w , EI_w , CLR_w , INC_w, LA_w , EA_w , LB_w , SU_w , AD_w , EU_w , LO_w;
|
39 |
|
|
assign EP = EP_w;
|
40 |
|
|
assign CP = CP_w;
|
41 |
|
|
assign CW = CW_w;
|
42 |
|
|
assign LOAD = LOAD_w;
|
43 |
|
|
assign CS = CS_w;
|
44 |
|
|
assign LI = LI_w;
|
45 |
|
|
assign LM = LM_w;
|
46 |
|
|
assign CE = CE_w;
|
47 |
|
|
assign EI = EI_w;
|
48 |
|
|
assign INC = INC_w;
|
49 |
|
|
assign CLR = CLR_w;
|
50 |
|
|
assign LA = LA_w;
|
51 |
|
|
assign EA = EA_w;
|
52 |
|
|
assign LB = LB_w;
|
53 |
|
|
assign SU = SU_w;
|
54 |
|
|
assign AD = AD_w;
|
55 |
|
|
assign EU = EU_w;
|
56 |
|
|
assign LO = LO_w;
|
57 |
|
|
assign DATA_OUT1 = bus_9;
|
58 |
|
|
assign IR_OUT1 = IR_OUT_1_w;
|
59 |
|
|
assign IR_OUT2 = bus_5_1;
|
60 |
|
|
assign ADDR_OUT1 = MUX_IN;
|
61 |
|
|
assign PC_OUT = bus_5;
|
62 |
|
|
assign MAR_OUT = MAR_OUT_w;
|
63 |
|
|
assign ACCUMULATOR_OUT = ALU_A_w;
|
64 |
|
|
assign OR_out = DATA_OUTPUT;
|
65 |
|
|
assign B_REG = ALU_B_w;
|
66 |
|
|
assign ALU_OUT = bus_9_1;
|
67 |
|
|
PC_4 UUT1 (.clk(clk) , .rst(rst) , .EP(EP_w) , .CP(CP_w) , .PC_OUT(bus_5));
|
68 |
|
|
MAR UUT2(.clk(clk) , .LM(LM_w) , .MAR_IN(bus_5 | bus_5_1) , .MAR_OUT(MAR_OUT_w));
|
69 |
|
|
SRAM_8 UUT3(.clk(clk) , .ADDR(MAR_OUT_w) , .CE(CE_w) ,.DATA_OUT(bus_9));
|
70 |
|
|
IR_8 UUT4(.clk(clk) , .rst(rst) , .LI(LI_w) , .EI(EI_w) ,.DATA_IN(bus_9) , .IR_OUT_1(IR_OUT_1_w) , .IR_OUT_2(bus_5_1));
|
71 |
|
|
ADDR_ROM UUT5(.CS(CS_w) , .ADDR(IR_OUT_1_w) , .ADDR_OUT(MUX_IN));
|
72 |
|
|
PRESET_COUNT UUT6(.clk(clk) , .rst(rst) , .LOAD(LOAD_w) , .CLR(CLR_w) , .INC(INC_w) , .COUNT_IN(MUX_IN) , .COUNT_OUT(COUNT_OUT));
|
73 |
|
|
CONTROL_ROM UUT7(.ADDR_IN(COUNT_OUT) , .CW(CW_w));
|
74 |
|
|
MICRO_DECODER UUT8(.CW(CW_w) , .EP(EP_w) , .CP(CP_w) , .LM(LM_w) ,.CE(CE_w), .LI(LI_w) , .EI(EI_w) , .CS(CS_w) , .LOAD(LOAD_w) , .CLR(CLR_w) , .INC(INC_w) , .LA(LA_w) , .EA(EA_w) , .LB(LB_w) , .SU(SU_w) , .AD(AD_w) , .EU(EU_w) , .LO(LO_w));
|
75 |
|
|
ACC_8 UUT9(.clk(clk) , .ACC_IN(bus_9 | bus_9_1) , .LA(LA_w) , .EA(EA_w) , .ACC_OUT_ALU(ALU_A_w) , .ACC_OUT_BUS(bus_9_2));
|
76 |
|
|
B_REG_8 UUT10(.clk(clk) , .LB(LB_w) , .B_IN(bus_9) , .B_OUT(ALU_B_w));
|
77 |
|
|
OUT_REG_8 UUT11(.clk(clk) , .OUT_IN(bus_9_2) , .LO(LO_w) , .OUT_P(DATA_OUTPUT));
|
78 |
|
|
ALU_8 UUT12(.ALU_A(ALU_A_w) ,.ALU_B(ALU_B_w) ,.SU(SU_w) , .AD(AD_w) , .EU(EU_w) ,.ALU_OUT(bus_9_1));
|
79 |
|
|
endmodule
|
80 |
|
|
|
81 |
|
|
module PC_4(input clk , input rst , input EP , input CP , output [4:0] PC_OUT);
|
82 |
|
|
reg [4:0] PC_OUT_r;
|
83 |
|
|
assign PC_OUT = EP ? PC_OUT_r : 5'h00;
|
84 |
|
|
always@(posedge clk or posedge rst)
|
85 |
|
|
begin
|
86 |
|
|
if(rst)
|
87 |
|
|
PC_OUT_r <= 5'b00000;
|
88 |
|
|
else if(CP)
|
89 |
|
|
PC_OUT_r <= PC_OUT_r + 1'b1;
|
90 |
|
|
end
|
91 |
|
|
endmodule
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
module MAR(input clk , input LM , input [4:0] MAR_IN , output [4:0] MAR_OUT);
|
95 |
|
|
reg[4:0]MAR_r;
|
96 |
|
|
assign MAR_OUT = MAR_r;
|
97 |
|
|
always@(posedge clk)
|
98 |
|
|
begin
|
99 |
|
|
if(~LM)
|
100 |
|
|
MAR_r <= MAR_IN;
|
101 |
|
|
end
|
102 |
|
|
endmodule
|
103 |
|
|
|
104 |
|
|
module SRAM_8(input clk , input [4:0] ADDR , input CE , output[8:0] DATA_OUT);
|
105 |
|
|
reg [8:0] SRAM [15:0] ;// A SRAM with 16 locations with each location capable of holding 8-bit of DATA
|
106 |
|
|
assign DATA_OUT = (~CE) ? SRAM[ADDR] : 9'h000;
|
107 |
|
|
always@(posedge clk)
|
108 |
|
|
begin
|
109 |
|
|
SRAM[0] <= 9'b000001001; //LDA 09 instruction - Load the contents of memory location 09 into the accumulator
|
110 |
|
|
SRAM[1] <= 9'b000101010; // ADD 0A instruction - Add the contents of Accumulator with the contents of memory location 0A and store the result in Accumulator
|
111 |
|
|
SRAM[2] <= 9'b001001011; // SUB 0B - Add the contents of Accumulator that is obtained from previous instruction with the contents of memory location 0B and store the result in Accumulator
|
112 |
|
|
SRAM[3] <= 9'b0011xxxxx; // OUT instruction - To output the content of accumulator that is obtained from previous addition operation
|
113 |
|
|
SRAM[4] <= 9'b111111111; // HLT instruction - To stop the execution of instructions
|
114 |
|
|
SRAM[5] <= 9'b111111111; // Unused memory locations are filled with FF
|
115 |
|
|
SRAM[6] <= 9'b111111111; // Unused memory locations are filled with FF
|
116 |
|
|
SRAM[7] <= 9'b111111111; //Unused memory locations are filled with FF
|
117 |
|
|
SRAM[8] <= 9'b111111111; // Unused memory locations are filled with FF
|
118 |
|
|
SRAM[9] <= 9'b000000001; // 01H is the 8-bit value stored in the location 09
|
119 |
|
|
SRAM[10]<= 9'b000000010; // 02H is the 8-bit value stored in the location 0A
|
120 |
|
|
SRAM[11]<= 9'b000000001; // 01H is the 8-bit value stored in the location 0B
|
121 |
|
|
SRAM[12]<= 9'b111111111; // Unused memory locations are filled with FF
|
122 |
|
|
SRAM[13]<= 9'b111111111; // Unused memory locations are filled with FF
|
123 |
|
|
SRAM[14]<= 9'b111111111; // Unused memory locations are filled with FF
|
124 |
|
|
SRAM[15]<= 9'b111111111; // Unused memory locations are filled with FF
|
125 |
|
|
end
|
126 |
|
|
endmodule
|
127 |
|
|
|
128 |
|
|
module IR_8 (input clk , input rst , input LI , input EI, input [8:0] DATA_IN , output[3:0] IR_OUT_1 , output [4:0] IR_OUT_2);
|
129 |
|
|
reg [8:0] IR_r;
|
130 |
|
|
assign IR_OUT_1 = IR_r[8:5];
|
131 |
|
|
assign IR_OUT_2 = EI ? IR_r[4:0] : 5'h00;
|
132 |
|
|
always@(posedge clk or posedge rst)
|
133 |
|
|
begin
|
134 |
|
|
if(rst)
|
135 |
|
|
IR_r <= 9'h000;
|
136 |
|
|
else if(~LI)
|
137 |
|
|
IR_r <= DATA_IN;
|
138 |
|
|
end
|
139 |
|
|
endmodule
|
140 |
|
|
|
141 |
|
|
module ADDR_ROM(input CS , input[3:0] ADDR , output[4:0] ADDR_OUT);
|
142 |
|
|
reg [4:0] AR [15:0];
|
143 |
|
|
assign ADDR_OUT = CS ? AR[ADDR] : 5'h00;
|
144 |
|
|
always @(ADDR)
|
145 |
|
|
begin
|
146 |
|
|
AR[0] <= 5'b00100; // LDA Routine Address
|
147 |
|
|
AR[1] <= 5'b00111; // ADD Routine Address
|
148 |
|
|
AR[2] <= 5'b01100; // SUB Routine Address
|
149 |
|
|
AR[3] <= 5'b10001; // OUT Routine Address
|
150 |
|
|
AR[4] <= 5'bxxxxx;
|
151 |
|
|
AR[5] <= 5'bxxxxx;
|
152 |
|
|
AR[6] <= 5'bxxxxx;
|
153 |
|
|
AR[7] <= 5'bxxxxx;
|
154 |
|
|
AR[8] <= 5'bxxxxx;
|
155 |
|
|
AR[9] <= 5'bxxxxx;
|
156 |
|
|
AR[10] <= 5'bxxxxx;
|
157 |
|
|
AR[11] <= 5'bxxxxx;
|
158 |
|
|
AR[12] <= 5'bxxxxx;
|
159 |
|
|
AR[13] <= 5'bxxxxx;
|
160 |
|
|
AR[14] <= 5'bxxxxx;
|
161 |
|
|
AR[15] <= 5'bxxxxx;
|
162 |
|
|
end
|
163 |
|
|
endmodule
|
164 |
|
|
|
165 |
|
|
|
166 |
|
|
module PRESET_COUNT(input clk , input rst , input INC , input CLR , input LOAD , input [4:0] COUNT_IN , output [4:0] COUNT_OUT); // Micro-Routine Program Counter
|
167 |
|
|
reg [4:0] COUNT_OUT_r;
|
168 |
|
|
assign COUNT_OUT = COUNT_OUT_r;
|
169 |
|
|
always@(posedge clk or posedge rst)
|
170 |
|
|
begin
|
171 |
|
|
if(rst)
|
172 |
|
|
COUNT_OUT_r <= 5'b0000;
|
173 |
|
|
else if(LOAD)
|
174 |
|
|
COUNT_OUT_r <= COUNT_IN;
|
175 |
|
|
else if(INC) // Always associate a signal that must occur along with CLOCK EDGE , for an operation to be done. This is the correct way.
|
176 |
|
|
COUNT_OUT_r <= COUNT_OUT_r + 1'b1;
|
177 |
|
|
else if(CLR)
|
178 |
|
|
COUNT_OUT_r <= COUNT_IN;
|
179 |
|
|
end
|
180 |
|
|
endmodule
|
181 |
|
|
|
182 |
|
|
module CONTROL_ROM(input [4:0] ADDR_IN , output [16:0] CW);
|
183 |
|
|
reg [16:0] CR [19:0];
|
184 |
|
|
assign CW = CR[ADDR_IN];
|
185 |
|
|
always@(ADDR_IN)
|
186 |
|
|
// EP CP LM* CE* LI* EI CS LOAD CLR INC LA* EA LB* SU AD EU LO*
|
187 |
|
|
// ************************ FETCH ROUTINE ***************************
|
188 |
|
|
// 1 0 0 1 1 0 0 0 0 1 1 0 1 0 0 0 1
|
189 |
|
|
// 0 1 1 1 1 0 0 0 0 1 1 0 1 0 0 0 1
|
190 |
|
|
// 0 0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 1
|
191 |
|
|
// 0 0 1 1 1 0 1 1 0 0 1 0 1 0 0 0 1
|
192 |
|
|
// ********************** LDA ROUTINE ****************************
|
193 |
|
|
// 0 0 0 1 1 1 0 0 0 1 1 0 1 0 0 0 1
|
194 |
|
|
// 0 0 1 0 1 0 0 0 0 1 0 0 1 0 0 0 1
|
195 |
|
|
// 0 0 1 1 1 0 0 0 1 0 1 0 1 0 0 0 1
|
196 |
|
|
// ************************ADD ROUTINE ***************************
|
197 |
|
|
// 0 0 0 1 1 1 0 0 0 1 1 0 1 0 0 0 1
|
198 |
|
|
// 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1
|
199 |
|
|
// 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 0 1
|
200 |
|
|
// 0 0 1 1 1 0 0 0 0 1 0 0 1 0 0 1 1
|
201 |
|
|
// 0 0 1 1 1 0 0 0 1 0 1 0 1 0 0 0 1
|
202 |
|
|
// *********************** SUB ROUTINE ****************************
|
203 |
|
|
// 0 0 0 1 1 1 0 0 0 1 1 0 1 0 0 0 1
|
204 |
|
|
// 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1
|
205 |
|
|
// 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 0 1
|
206 |
|
|
// 0 0 1 1 1 0 0 0 0 1 0 0 1 0 0 1 1
|
207 |
|
|
// 0 0 1 1 1 0 0 0 1 0 1 0 1 0 0 1 1
|
208 |
|
|
// ********************** OUT ROUTINE ****************************
|
209 |
|
|
// 0 0 0 1 1 1 0 0 0 1 1 0 1 0 0 1 1
|
210 |
|
|
// 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 1 0
|
211 |
|
|
// 0 0 1 1 1 0 0 0 1 0 1 0 1 0 0 1 1
|
212 |
|
|
begin
|
213 |
|
|
// Fetch Micro-routine
|
214 |
|
|
CR[0] <= 17'b10011000011010001; // EP and LM signals activated and Preset Counter Incremented
|
215 |
|
|
CR[1] <= 17'b01111000011010001; // CP signal activated and Preset Counter Incremented
|
216 |
|
|
CR[2] <= 17'b00100000011010001; // CE and LI signals activated and Preset Counter Incremented
|
217 |
|
|
CR[3] <= 17'b00111011001010001; // CS and Preset LOAD signal activated.
|
218 |
|
|
// LDA Micro-routine
|
219 |
|
|
CR[4] <= 17'b00011100011010001 ; // LM , EI signals activated and Preset Counter Incremented
|
220 |
|
|
CR[5] <= 17'b00101000010010001; // CE and LA signals activated and Preset Counter Incremented
|
221 |
|
|
CR[6] <= 17'b00111000101000001; // Preset CLR signal activated
|
222 |
|
|
// ADD Micro-routine
|
223 |
|
|
CR[7] <= 17'b00011100011010001; // LM , EI signals activated and Preset Counter Incremented
|
224 |
|
|
CR[8] <= 17'b00101000011000001; // CE and LB signals activated and Preset Counter Incremented
|
225 |
|
|
CR[9] <= 17'b00111000011010101; // AD signal activated and Preset Counter Incremented
|
226 |
|
|
CR[10] <= 17'b00111000010010011; // EU and LA signals activated and Preset Counter Incremented
|
227 |
|
|
CR[11] <= 17'b00111000101010001; // Preset CLR signal activated
|
228 |
|
|
// SUB Micro-routine
|
229 |
|
|
CR[12] <= 17'b00011100011010001; // LM , EI signals activated and Preset Counter Incremented
|
230 |
|
|
CR[13] <= 17'b00101000011000001; // CE and LB signals activated and Preset Counter Incremented
|
231 |
|
|
CR[14] <= 17'b00111000011011001; // SU signal activated and Preset Counter Incremented
|
232 |
|
|
CR[15] <= 17'b00111000010010011; // EU and LA signals activated and Preset Counter Incremented
|
233 |
|
|
CR[16] <= 17'b00111000101010011; // Preset CLR signal activated
|
234 |
|
|
// Actually this design of CPU requires 5-bit address [i.e. memory with 32 memory locations] in order to accomodate the micro-routines of all instructions. The design has to be accordingly changed.
|
235 |
|
|
// OUT Micro-routine
|
236 |
|
|
CR[17] <= 17'b00011100011010011;
|
237 |
|
|
CR[18] <= 17'b00111000011110010;
|
238 |
|
|
CR[19] <= 17'b00111000101010011;
|
239 |
|
|
// NOP Micro-routine
|
240 |
|
|
//CR[14] <= 17'b00111000001010001;
|
241 |
|
|
end
|
242 |
|
|
endmodule
|
243 |
|
|
|
244 |
|
|
module MICRO_DECODER(input [16:0] CW , output EP , CP , LM , CE , LI , EI , CS , LOAD , CLR , INC , LA , EA , LB , SU , AD , EU , LO);
|
245 |
|
|
assign EP = CW[16];
|
246 |
|
|
assign CP = CW[15];
|
247 |
|
|
assign LM = CW[14];
|
248 |
|
|
assign CE = CW[13];
|
249 |
|
|
assign LI = CW[12];
|
250 |
|
|
assign EI = CW[11];
|
251 |
|
|
assign CS = CW[10];
|
252 |
|
|
assign LOAD = CW[9];
|
253 |
|
|
assign CLR = CW[8];
|
254 |
|
|
assign INC = CW[7];
|
255 |
|
|
assign LA = CW[6];
|
256 |
|
|
assign EA = CW[5];
|
257 |
|
|
assign LB = CW[4];
|
258 |
|
|
assign SU = CW[3];
|
259 |
|
|
assign AD = CW[2];
|
260 |
|
|
assign EU = CW[1];
|
261 |
|
|
assign LO = CW[0];
|
262 |
|
|
endmodule
|
263 |
|
|
|
264 |
|
|
module ACC_8(input clk , input [8:0] ACC_IN , input LA , input EA , output [8:0] ACC_OUT_ALU , output[8:0] ACC_OUT_BUS);
|
265 |
|
|
reg [8:0] ACC_OUT_r;
|
266 |
|
|
assign ACC_OUT_ALU = ACC_OUT_r;
|
267 |
|
|
assign ACC_OUT_BUS = EA ? ACC_OUT_r : 9'h000;
|
268 |
|
|
always@(posedge clk)
|
269 |
|
|
begin
|
270 |
|
|
if(~LA)
|
271 |
|
|
ACC_OUT_r <= ACC_IN;
|
272 |
|
|
end
|
273 |
|
|
endmodule
|
274 |
|
|
|
275 |
|
|
module B_REG_8(input clk , input [8:0] B_IN , input LB , output [8:0] B_OUT);
|
276 |
|
|
reg [8:0] B_OUT_r;
|
277 |
|
|
assign B_OUT = B_OUT_r;
|
278 |
|
|
always@(posedge clk)
|
279 |
|
|
begin
|
280 |
|
|
if(~LB)
|
281 |
|
|
B_OUT_r <= B_IN;
|
282 |
|
|
end
|
283 |
|
|
endmodule
|
284 |
|
|
|
285 |
|
|
module OUT_REG_8(input clk , input [8:0] OUT_IN , input LO , output [8:0]OUT_P );
|
286 |
|
|
reg [8:0] OUT_P_r;
|
287 |
|
|
assign OUT_P = OUT_P_r;
|
288 |
|
|
always@(posedge clk)
|
289 |
|
|
begin
|
290 |
|
|
if(~LO)
|
291 |
|
|
OUT_P_r<= OUT_IN;
|
292 |
|
|
end
|
293 |
|
|
endmodule
|
294 |
|
|
|
295 |
|
|
module ALU_8(input[8:0] ALU_A , input [8:0] ALU_B , input SU , input AD , input EU , output [8:0]ALU_OUT); // Here addition of AD signal , eliminated the need for a separate multiplexer for the accumulator.
|
296 |
|
|
wire [8:0] ALU_OUT_w;
|
297 |
|
|
assign ALU_OUT_w = SU ? ALU_A - ALU_B : AD ? ALU_A + ALU_B : ALU_OUT_w;
|
298 |
|
|
assign ALU_OUT = EU ? ALU_OUT_w : 9'h000;
|
299 |
|
|
endmodule
|
300 |
|
|
|