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

Subversion Repositories sap_microprogrammed_processor

[/] [sap_microprogrammed_processor/] [branches/] [MCPU8_1.v] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
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
 

powered by: WebSVN 2.1.0

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