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

Subversion Repositories sap_1_vertical_microprogrammed_processor

[/] [sap_1_vertical_microprogrammed_processor/] [branches/] [M2CPU8.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sssayeekum
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Company: 
4
// Engineer: 
5
// 
6
// Create Date:    21:09:17 05/28/2022 
7
// Design Name: 
8
// Module Name:    M2CPU8 
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
// A bus output can be connected to multiple inputs. But a bus cannot be connected to multiple outputs. This generates 'The GIVEN BUS IS DRIVEN BY MULTIPLE DRIVERS in Xilinx ISE 14.7 Webpack
22
module M2CPU8(input clk , input rst , output EP , output CP , output[4:0] PC_OUT_o , output [4:0] SRAM_ADDR_o , output LM , output CE_o , output [3:0] IR_1_OUT_o , output [4:0] IR_2_OUT_o, output [8:0] SRAM_OUT , output LI_o , output EI_o , output CS_o , output LOAD_o , output INC_o , output CLR_o , output LA_o , output EA_o , output SU_o , output AD_o , output EU_o , output LB_o , output LO_o , output [8:0]OUT_o , output[4:0] PRE_OUT_o ,output [8:0] ACC_OUT_o , output[8:0] ACC_OUT_bus_o , output [8:0] B_o , output[8:0] ALU_OUT_o , output[8:0] ALU_OUT_bus);
23
wire [8:0] bus_9 , ACC_MUX_w , bus_9_1 , bus_9_2 , ALU_OUT_w , A_OUT_w , B_OUT_w , OUT_w ;
24
wire [8:0] ROM_OUT_w;
25
wire EP_w , CP_w , LM_w ,  CE_w , LI_w, CS_w , LOAD_w , INC_w , CLR_w , LA_w , EA_w ,  SU_w , AD_w , EU_w , LB_w , LO_w;
26
wire [4:0] bus_5 , bus_5_1 , PC_OUT_w , SRAM_ADDR_w , MAR_IN_w , AR_OUT_w , PRE_OUT_w ;
27
wire [3:0] INSTR_w;
28
assign EP = EP_w;
29
assign CP = CP_w;
30
assign LM = LM_w;
31
assign SRAM_OUT = bus_9;
32
assign CE_o = CE_w;
33
assign LI_o = LI_w;
34
assign EI_o = EI_w;
35
assign CS_o = CS_w;
36
assign LOAD_o = LOAD_w;
37
assign INC_o = INC_w;
38
assign CLR_o = CLR_w;
39
assign LA_o = LA_w;
40
assign EA_o = EA_w;
41
assign SU_o = SU_w;
42
assign AD_o = AD_w;
43
assign EU_o = EU_w;
44
assign LB_o = LB_w;
45
assign LO_o = LO_w;
46
assign OUT_o = OUT_w;
47
assign PRE_OUT_o = PRE_OUT_w;
48
assign PC_OUT_o = bus_5;
49
assign SRAM_ADDR_o = SRAM_ADDR_w;
50
assign ACC_OUT_o = A_OUT_w;
51
assign IR_1_OUT_o = INSTR_w;
52
assign IR_2_OUT_o = bus_5_1;
53
assign ACC_OUT_bus_o = bus_9_2;
54
assign ALU_OUT_bus = bus_9_1;
55
assign ALU_OUT_o = ALU_OUT_w;
56
assign B_o = B_OUT_w;
57
PC_4 UUT1(.clk(clk) , .rst(rst) , .EP(EP_w),.CP(CP_w)  , .PC_OUT(bus_5));
58
MAR_4 UUT2(.clk(clk) , .MAR_IN(bus_5| bus_5_1) ,  .LM(LM_w) , .MAR_OUT(SRAM_ADDR_w));
59
SRAM_8 UUT3(.SRAM_ADDR(SRAM_ADDR_w) , .CE(CE_w),.SRAM_OUT(bus_9));
60
IR_8 UUT4(.clk(clk) , .rst(rst), .LI(LI_w) , .EI(EI_w) , .SRAM_IN(bus_9) , .IR_OUT_1(INSTR_w) , .IR_OUT_2(bus_5_1));
61
ADDR_ROM UUT5 (.INSTR(INSTR_w) , .CS(CS_w) , .AR_OUT(AR_OUT_w));
62
PRESET_COUNTER UUT6(.clk(clk) , .rst(rst) , .AR_ROM_IN(AR_OUT_w) , .LOAD(LOAD_w) , .INC(INC_w) , .CLR(CLR_w) , .PRE_OUT(PRE_OUT_w));
63
MICROCODE_ROM UUT7(.PRE_IN(PRE_OUT_w) , .ROM_OUT(ROM_OUT_w));
64
MICROCODE_DECODER UUT8(.OPCODE(ROM_OUT_w) , .EP_o(EP_w) , .CP_o(CP_w) , .CE_o(CE_w) , .LM_o(LM_w) , .LI_o(LI_w) , .EI_o(EI_w) ,.CS_o(CS_w) , .LOAD_o(LOAD_w) , .INC_o(INC_w) , .CLR_o(CLR_w) , .LA_o(LA_w) , .EA_o(EA_w) , .SU_o(SU_w) , .AD_o(AD_w) , .EU_o(EU_w) , .LB_o(LB_w) , .LO_o(LO_w));
65
ACC UUT9(.clk(clk) , .LA(LA_w) , .EA(EA_w) , .ACC_IN(bus_9 | bus_9_1) , .ACC_OUT_adder(A_OUT_w) , .ACC_OUT_bus(bus_9_2));
66
ALU_8  UUT10(.A(A_OUT_w) , .B(B_OUT_w) , .EU(EU_w) , .SU(SU_w), .AD(AD_w) , .ALU_OUT_bus(bus_9_1),.ALU_OUT_o(ALU_OUT_w));
67
B_REG UUT11(.clk(clk) , .LB(LB_w) , .B_IN(bus_9) , .B_OUT(B_OUT_w));
68
OUT_REG UUT12(.clk(clk) , .LO(LO_w) , .OUT_IN(bus_9_2) , .OUT_o(OUT_w));
69
endmodule
70
 
71
module PC_4(input clk , input rst , input EP , input CP ,  output [4:0] PC_OUT);
72
reg [4:0] PC_r;
73
assign PC_OUT = EP ? PC_r : 5'h00;
74
always@(posedge clk or posedge rst)
75
begin
76
if(rst)
77
PC_r <= 5'b00000; // At the positive edge of rst , the 4-bit Program Counter gets reset to 4'b0000 or 4'h0.
78
else if(CP) // During positive edge of clock , if CP is logic 1 , the 4-bit PC gets incremented by 1.
79
PC_r <= PC_r + 1'b1;
80
end
81
endmodule
82
 
83
module MAR_4(input clk ,input [4:0] MAR_IN ,  input LM , output[4:0] MAR_OUT);
84
reg [4:0] MAR_r;
85
assign MAR_OUT = MAR_r;
86
always@(posedge clk)
87
begin
88
if(~LM)// When LM = 0 , the input will be loaded into MAR.
89
MAR_r <= MAR_IN;
90
end
91
endmodule
92
 
93
module SRAM_8(input [4:0] SRAM_ADDR , input CE , output [8:0] SRAM_OUT); // The SRAM follows ASYNCHRONOUS WRITE and ASYNCHRONOUS READ.
94
reg [8:0] SRAM [15:0]; // SRAM is a memory with 16 memory locations , with each location capable of holding 8-bits of data
95
assign SRAM_OUT = (~CE) ? SRAM[SRAM_ADDR] : 9'h000; // ASYNCHRONOUS READ.
96
always@(SRAM_ADDR) // ASYNCHRONOUS WRITE
97
begin
98
SRAM[0] <= 9'b000001001; //LDA 09 ; Here LDA is the opcode or instruction and 09 is the SRAM address from where data will be loaded into accumulator.
99
SRAM[1] <= 9'b000101010; // ADD 0A ; - Add the contents of Accumulator with the contents of memory location 0A and store the result in Accumulator
100
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 
101
SRAM[3] <= 9'b0011xxxxx; //  OUT ; Subtract the contents of the accumulator 
102
SRAM[4] <= 9'hFFF; // 
103
SRAM[5] <= 9'hFFF; // 
104
SRAM[6] <= 9'hFFF; // Unused memory locations are filled with FF
105
SRAM[7] <= 9'hFFF; // Unused memory locations are filled with FF
106
SRAM[8] <= 9'hFFF; // Unused memory locations are filled with FF
107
SRAM[9] <= 9'h001; //01H is the 8-bit value stored in the location 09
108
SRAM[10] <= 9'h006; //06H is the 8-bit value stored in the location 0A
109
SRAM[11] <= 9'h003; //03H is the 8-bit value stored in the location 0B
110
SRAM[12] <= 9'hFFF;// Unused memory locations are filled with FF
111
SRAM[13] <= 9'hFFF;// Unused memory locations are filled with FF
112
SRAM[14] <= 9'hFFF;// Unused memory locations are filled with FF
113
SRAM[15] <= 9'hFFF;// Unused memory locations are filled with FF
114
end
115
endmodule
116
 
117
module IR_8(input clk , input rst , input LI , input EI , input [8:0] SRAM_IN , output [3:0] IR_OUT_1 ,output [4:0] IR_OUT_2);
118
reg [8:0] IR_8_r;
119
assign IR_OUT_1 = IR_8_r[8:5];
120
assign IR_OUT_2 = (~EI) ? IR_8_r[4:0] : 5'h00;
121
always@(posedge clk or posedge rst)
122
begin
123
if(rst)
124
IR_8_r <= 9'h000;
125
else if(~LI)
126
IR_8_r <= SRAM_IN;
127
end
128
endmodule
129
 
130
module ADDR_ROM(input [3:0] INSTR , input CS , output [4:0] AR_OUT);// Holds the Micro-routine for a Macro-Instruction fetched from SRAM
131
reg [4:0] AR_OUT_r[15:0];
132
assign AR_OUT = AR_OUT_r[INSTR];// Instruction Fetched from IR serves as the address for reading data from Address ROM. The output of Address ROM is the starting address of a Micro-Routine.
133
always@(CS) // Whenever the CS[Chip Select] signal is activated , content of a ROM address will be output.
134
begin
135
AR_OUT_r[0] <= 5'b00100;
136
AR_OUT_r[1] <= 5'b00111;
137
AR_OUT_r[2] <= 5'b01100;
138
AR_OUT_r[3] <= 5'b10001;
139
AR_OUT_r[4] <= 5'hFF;
140
AR_OUT_r[5] <= 5'hFF;
141
AR_OUT_r[6] <= 5'hFF;
142
AR_OUT_r[7] <= 5'hFF;
143
AR_OUT_r[8] <= 5'hFF;
144
AR_OUT_r[9] <= 5'hFF;
145
AR_OUT_r[10] <= 5'hFF;
146
AR_OUT_r[11] <= 5'hFF;
147
AR_OUT_r[12] <= 5'hFF;
148
AR_OUT_r[13] <= 5'hFF;
149
AR_OUT_r[14] <= 5'hFF;
150
AR_OUT_r[15] <= 5'hFF;
151
end
152
endmodule
153
 
154
module PRESET_COUNTER (input clk , input rst , input [4:0] AR_ROM_IN , input LOAD , input INC , input CLR , output [4:0] PRE_OUT); // This is called Microprogram Counter
155
reg [4:0] PRE_OUT_r;
156
assign PRE_OUT = PRE_OUT_r;
157
always@(posedge clk or posedge rst) // Signals separated by "or" in sensitivity list of "always" statement are Asynchronous.
158
begin
159
if(rst)
160
PRE_OUT_r <= 5'h00;
161
else if(LOAD)
162
PRE_OUT_r <= AR_ROM_IN;
163
else if(INC)
164
PRE_OUT_r <= PRE_OUT_r + 1'b1;
165
else if(CLR) // Difference between RST and CLR is RST is asynchronous signal[Occurs independent of clock edge] whereas CLR is Synchronous signal[i.e. occurs when a clock edge has occured]
166
PRE_OUT_r <= 5'h00;
167
end
168
endmodule
169
 
170
module MICROCODE_ROM(input [4:0] PRE_IN , output [8:0] ROM_OUT);
171
reg [8:0] ROM_OUT_r[19:0];
172
assign ROM_OUT = ROM_OUT_r[PRE_IN];// The output of PRESETTABLE COUNTER acts as the input for reading the content of MICROCODE ROM
173
always@(PRE_IN)
174
begin
175
//   CP   EP  LM   CE  LI  EI CS LOAD  INC  CLR   LA  EA  SU  EU  LB  LO
176
//    |------- M1------------------|----------M2-----------------|------LOAD-----|------INC-----|--------CLR--------|
177
//          8 7 6                         5  4  3                         2               1                0  
178
//          0 0 0 (EP)                    0  0  0 (LI)
179
//          0 0 1 (CP)                    0  0  1 (LM)
180
//          0 1 0 (CE)                    0  1  0 (LB) 
181
//          0 1 1 (EI)                    0  1  1 (LO)                   
182
//          1 0 0 (CS)                    1  0  0 (LA)  
183
//          1 0 1 (EA)                                        1  0  1 (SU) 
184
//          1 1 0 (EU)                    1  1  0 (AD)
185
//          1 1 1 (NOP)                   1  1  1 (NOP)           
186
 
187
// Fetch Routine
188
ROM_OUT_r[0] <= 9'b000001010 ;// EP and LM  activated and Preset Counter Incremented
189
ROM_OUT_r[1] <= 9'b001111010; // CP  activated and Preset Counter Incremented
190
ROM_OUT_r[2] <= 9'b010000010; // CE and LI activated and Preset Counter Incremented
191
ROM_OUT_r[3] <= 9'b100111100; // CS and LOAD activated
192
// LDA Routine
193
ROM_OUT_r[4] <= 9'b011001010; // EI and LM activated and Preset Counter Incremented 
194
ROM_OUT_r[5] <= 9'b010100010; // CE and LA activated and Preset Counter Incremented
195
ROM_OUT_r[6] <= 9'b111111001; // Preset CLR
196
// ADD Routine
197
ROM_OUT_r[7] <= 9'b011001010; // EI and LM activated and Preset Counter Incremented 
198
ROM_OUT_r[8] <= 9'b010010010; // CE and LB activated and Preset Counter Incremented
199
ROM_OUT_r[9] <= 9'b111110010; // AD activated and Preset Counter Incremented
200
ROM_OUT_r[10] <= 9'b110100010; // EU and LA activated and Preset Counter Incremented
201
ROM_OUT_r[11] <= 9'b111111001; // Preset CLR
202
// SUB Routine
203
ROM_OUT_r[12] <= 9'b011001010; // EI and LM activated and Preset Counter Incremented 
204
ROM_OUT_r[13] <= 9'b010010010; // CE and LB activated and Preset Counter Incremented
205
ROM_OUT_r[14] <= 9'b111101010; // SU activated and Preset Counter Incremented 
206
ROM_OUT_r[15] <= 9'b110100010; // EU and LA activated and Preset Counter Incremented
207
 ROM_OUT_r[16] <= 9'b111111001; // Preset CLR. Actually this CPU requires 4-bit Address for SRAM and 5-bit address for Microcode ROM. So that needs to be changed.
208
// OUT Routine
209
ROM_OUT_r[17] <= 9'b011001010; // EI and LM activated and Preset Counter Incremented  
210
ROM_OUT_r[18] <= 9'b101011010; // EA and LO activated and Preset Counter Incremented
211
ROM_OUT_r[19] <= 9'b111111001; // Preset CLR
212
end
213
endmodule
214
 
215
module MICROCODE_DECODER(input [8:0] OPCODE , output EP_o , output CP_o , output LM_o, output CE_o ,output LI_o , output EI_o , output CS_o , output LOAD_o , output INC_o , output CLR_o , output LA_o , output EA_o , output SU_o , output AD_o , output EU_o , output LB_o , output LO_o);
216
// M1 Decoder
217
assign EP_o = ~OPCODE[8] & ~OPCODE[7] & ~OPCODE[6]; //0 0 0
218
assign CP_o = ~OPCODE[8] & ~OPCODE[7] & OPCODE[6]; // 0 0 1
219
assign CE_o = ~(~OPCODE[8] & OPCODE[7] & ~OPCODE[6]);// 0 1 0
220
assign EI_o = ~(~OPCODE[8] & OPCODE[7] & OPCODE[6]);// 0 1 1
221
assign CS_o = OPCODE[8] & ~OPCODE[7] & ~OPCODE[6];// 1 0 0
222
assign EA_o = OPCODE[8] & ~OPCODE[7] & OPCODE[6]; // 1 0 1
223
assign EU_o = OPCODE[8] & OPCODE[7] & ~OPCODE[6]; // 1 1 0
224
// M2 Decoder
225
assign LI_o = ~(~OPCODE[5] & ~OPCODE[4] & ~OPCODE[3]); // 0 0 0
226
assign LM_o = ~(~OPCODE[5] & ~OPCODE[4] & OPCODE[3]); // 0 0 1
227
assign LB_o = ~(~OPCODE[5] & OPCODE[4] & ~OPCODE[3]); // 0 1 0
228
assign LO_o = ~(~OPCODE[5] & OPCODE[4] & OPCODE[3]); // 0 1 1
229
assign LA_o = ~(OPCODE[5] & ~OPCODE[4] & ~OPCODE[3]); // 1 0 0
230
assign SU_o =  OPCODE[5] & ~OPCODE[4] & OPCODE[3]; // 1 0 1
231
assign AD_o = OPCODE[5] & OPCODE[4] & ~OPCODE[3]; // 1 1 0
232
 
233
assign LOAD_o = OPCODE[2];
234
assign INC_o = OPCODE[1];
235
assign CLR_o = OPCODE[0];
236
endmodule
237
 
238
 
239
module ACC(input clk , input LA , input EA , input [8:0] ACC_IN , output [8:0] ACC_OUT_adder , output[8:0] ACC_OUT_bus); // Any component[register or ALU] that interacts with a common data bus , must have ENABLE signal in it. When ENABLE signal is activated , the data stored in the component's register is transferred to the bus. When ENABLE signal is deactivated , the data gets retained within the component's register.
240
reg [8:0] ACC_OUT_r;
241
assign ACC_OUT_adder = ACC_OUT_r;
242
assign ACC_OUT_bus = EA ? ACC_OUT_r : 9'h000;
243
always @(posedge clk)
244
begin
245
if(~LA)
246
ACC_OUT_r <= ACC_IN;
247
end
248
endmodule
249
 
250
module ALU_8(input [8:0] A , input [8:0] B , input EU , input SU , input AD , output [8:0] ALU_OUT_bus , output[8:0] ALU_OUT_o);
251
wire [8:0] ALU_OUT_w;
252
assign ALU_OUT_w = SU ? A-B : AD ? A+B : ALU_OUT_w; // Here AD signal added to ADDER. When SU or AU is 0, the ALU_OUT_w will be holding its previous value. This is a change when c
253
assign ALU_OUT_o = ALU_OUT_w;
254
assign ALU_OUT_bus = EU ? ALU_OUT_w : 9'h000;
255
endmodule
256
 
257
module B_REG(input clk , input LB , input [8:0] B_IN , output [8:0] B_OUT);
258
reg [8:0] B_OUT_r;
259
assign B_OUT = B_OUT_r;
260
always@(posedge clk)
261
begin
262
if(~LB) // else block added here in order to avoid don't care value. This is a change when compared to hardwired processor
263
B_OUT_r <= B_IN;
264
else
265
B_OUT_r <= 9'h000;
266
end
267
endmodule
268
 
269
module OUT_REG(input clk , input LO , input [8:0] OUT_IN , output [8:0] OUT_o);
270
reg [8:0] OUT_o_r;
271
assign OUT_o = OUT_o_r;
272
always@(posedge clk)
273
begin
274
if(~LO) // else block added here in order to avoid don't care value. This is a change when compared to hardwired processor
275
OUT_o_r <= OUT_IN;
276
else
277
OUT_o_r <= 9'h000;
278
end
279
endmodule
280
 
281
 

powered by: WebSVN 2.1.0

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