1 |
2 |
sssayeekum |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Company:
|
4 |
|
|
// Engineer:
|
5 |
|
|
//
|
6 |
|
|
// Create Date: 16:57:26 08/26/2021
|
7 |
|
|
// Design Name:
|
8 |
|
|
// Module Name: CPU8_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 |
|
|
module CPU8_1(input clk , input rst , output [3:0] PC_OUT , output[5:0] T ,output [3:0] ADDR_out , output [7:0] DATA_OUT_1 , output [3:0] IR_OUT_w1 , output [3:0] IR_OUT_w2 , output [7:0] ALU_out , output LDA , output ADD , output SUB , output OUT , output HLT , output[7:0] DATA_OUT , output [7:0] ACC_OUT , output CP , output EP , output LM , output CE , output LI , output EI , output LA , output EA , output SU , output EU , output LB , output LO , output NOP);
|
22 |
|
|
wire CP_w , EP_w , LM_w , CE_w , LI_w , EI_w , LA_w , EA_w , SU_w , EU_w , LB_w , LO_w , NOP_w;
|
23 |
|
|
wire [3:0] ADDR_out_w , IR_OUT_1_w , IR_OUT_2_w;
|
24 |
|
|
wire [7:0] ALU_OUT_w , DATA_OUT_w1;
|
25 |
|
|
wire LDA_w1 , ADD_w2 , SUB_w3 , OUT_w4 , HLT_w5;
|
26 |
|
|
wire [3:0] bus_4;
|
27 |
|
|
wire [7:0] bus_8;
|
28 |
|
|
wire [7:0] bus_8_1;
|
29 |
|
|
wire [5:0] T_w;
|
30 |
|
|
wire [7:0] OR_w;
|
31 |
|
|
wire [7:0] ALU_A_w;
|
32 |
|
|
wire [7:0] ALU_B_w;
|
33 |
|
|
wire [7:0] ACC_OUT_w;
|
34 |
|
|
assign PC_OUT = bus_4;
|
35 |
|
|
assign ADDR_out = ADDR_out_w;
|
36 |
|
|
assign IR_OUT_w1 = IR_OUT_1_w;
|
37 |
|
|
assign IR_OUT_w2 = bus_4;
|
38 |
|
|
assign T = T_w;
|
39 |
|
|
assign DATA_OUT_1 = bus_8;
|
40 |
|
|
assign ALU_out = bus_8_1;
|
41 |
|
|
assign DATA_OUT = DATA_OUT_w1;
|
42 |
|
|
assign ACC_OUT = ALU_A_w;
|
43 |
|
|
assign LDA = LDA_w1;
|
44 |
|
|
assign ADD = ADD_w2;
|
45 |
|
|
assign SUB = SUB_w3;
|
46 |
|
|
assign OUT = OUT_w4;
|
47 |
|
|
assign HLT = HLT_w5;
|
48 |
|
|
assign CP = CP_w;
|
49 |
|
|
assign EP = EP_w;
|
50 |
|
|
assign LM = LM_w;
|
51 |
|
|
assign CE = CE_w;
|
52 |
|
|
assign LI = LI_w;
|
53 |
|
|
assign EI = EI_w;
|
54 |
|
|
assign LA = LA_w;
|
55 |
|
|
assign EA = EA_w;
|
56 |
|
|
assign SU = SU_w;
|
57 |
|
|
assign EU = EU_w;
|
58 |
|
|
assign LB = LB_w;
|
59 |
|
|
assign LO = LO_w;
|
60 |
|
|
assign NOP = NOP_w;
|
61 |
|
|
RC_6 UUT1(.clk(clk) , .rst(rst) , .NOP(NOP_w) , .HLT(HLT_w5), .OUT(T_w));
|
62 |
|
|
CU_8 UUT2 (.LDA(LDA_w1) , .ADD(ADD_w2) , .SUB(SUB_w3) , .OUT(OUT_w4) ,.T(T_w) , .CP(CP_w) , .EP(EP_w) , .LM(LM_w) , .CE(CE_w) , .LI(LI_w) , .EI(EI_w) , .LA(LA_w) , .EA(EA_w) , .SU(SU_w) , .EU(EU_w) , .LB(LB_w) , .LO(LO_w) , .NOP(NOP_w));
|
63 |
|
|
PC_4 UUT3(.clk(clk) ,.rst(rst) , .CP(CP_w) , .EP(EP_w) , .PC_OUT(bus_4));
|
64 |
|
|
MAR_4 UUT4(.clk(clk) , .LM(LM_w) , .ADDR(bus_4),.ADDR_out(ADDR_out_w));
|
65 |
|
|
SRAM_8 UUT5(.clk(clk) , .ADDR(ADDR_out_w) , .CE(CE_w) , .DATA_OUT(bus_8));
|
66 |
|
|
IR_8 UUT6(.clk(clk) , .rst(rst) , .LI(LI_w) , .EI(EI_w) , .IR_IN(bus_8) , .IR_OUT_1(IR_OUT_1_w) , .IR_OUT_2(bus_4));
|
67 |
|
|
ID_8 UUT7(.INSTR(IR_OUT_1_w) , .LDA(LDA_w1) , .ADD(ADD_w2) , .SUB(SUB_w3) , .OUT(OUT_w4) , .HLT(HLT_w5));
|
68 |
|
|
ACC_8 UUT8(.clk(clk) , .LA(LA_w) , .EA(EA_w) , .ACC_IN(bus_8 | bus_8_1) , .ACC_OUT_ALU(ALU_A_w) , .ACC_OUT_W_BUS(OR_w));
|
69 |
|
|
ALU8_1 UUT9(.A(ALU_A_w) , .B(ALU_B_w) , .SU(SU_w) , .EU(EU_w) , .ALU_OUT(bus_8_1));
|
70 |
|
|
B_REG_1 UUT10(.clk(clk) , .DATA_IN(bus_8) , .LB(LB_w) , .DATA_OUT(ALU_B_w));
|
71 |
|
|
OR_1 UUT11(.clk(clk) , .DATA_IN(OR_w) , .LO(LO_w) , .DATA_OUT(DATA_OUT_w1));
|
72 |
|
|
endmodule
|
73 |
|
|
|
74 |
|
|
module PC_4(input clk , input rst , input CP , input EP , output[3:0] PC_OUT); // Module 1//
|
75 |
|
|
reg [3:0] PC_OUT_r;
|
76 |
|
|
assign PC_OUT = EP ? PC_OUT_r : 4'hZ;
|
77 |
|
|
always@(posedge clk or posedge rst)
|
78 |
|
|
begin
|
79 |
|
|
if(rst)
|
80 |
|
|
PC_OUT_r <= 4'h0;
|
81 |
|
|
else if(CP)
|
82 |
|
|
PC_OUT_r <= PC_OUT_r + 1'b1;
|
83 |
|
|
end
|
84 |
|
|
endmodule
|
85 |
|
|
|
86 |
|
|
module MAR_4(input clk , input LM,input[3:0] ADDR,output[3:0] ADDR_out);
|
87 |
|
|
reg [3:0] ADDR_r;
|
88 |
|
|
assign ADDR_out = ADDR_r;
|
89 |
|
|
always@(posedge clk)
|
90 |
|
|
begin
|
91 |
|
|
if(~LM)
|
92 |
|
|
ADDR_r <= ADDR;
|
93 |
|
|
end
|
94 |
|
|
endmodule
|
95 |
|
|
|
96 |
|
|
module SRAM_8(input clk , input [3:0] ADDR , input CE , output[7:0] DATA_OUT);
|
97 |
|
|
reg [7:0] SRAM [15:0] ;// A SRAM with 16 locations with each location capable of holding 8-bit of DATA
|
98 |
|
|
assign DATA_OUT = (~CE) ? SRAM[ADDR] : 8'h00;
|
99 |
|
|
always@(posedge clk)
|
100 |
|
|
begin
|
101 |
|
|
SRAM[0] <= 8'b00001001; //LDA 09 instruction - Load the contents of memory location 09 into the accumulator
|
102 |
|
|
SRAM[1] <= 8'b00011010; // ADD 0A instruction - Add the contents of Accumulator with the contents of memory location 0A and store the result in Accumulator
|
103 |
|
|
SRAM[2] <= 8'b00011011; // ADD 0B instruction - Add the contents of Accumulator that is obtained from previous instruction with the contents of memory location 0B and store the result in Accumulator
|
104 |
|
|
SRAM[3] <= 8'b00101011; // SUB 0B instruction - Subtract the contents of Accumulator that is obtained from previous instruction with the contents of memory location 0C and store the result in Accumulator
|
105 |
|
|
SRAM[4] <= 8'b11100000; // OUT instruction - To output the content of accumulator that is obtained from previous subtraction operation
|
106 |
|
|
SRAM[5] <= 8'b11110000; // HLT instruction - To stop the execution of instructions
|
107 |
|
|
SRAM[6] <= 8'b11111111; // Unused memory locations are filled with FF
|
108 |
|
|
SRAM[7] <= 8'b11111111; //Unused memory locations are filled with FF
|
109 |
|
|
SRAM[8] <= 8'b11111111; // Unused memory locations are filled with FF
|
110 |
|
|
SRAM[9] <= 8'b00000001; // 01H is the 8-bit value stored in the location 09
|
111 |
|
|
SRAM[10]<= 8'b00000010; // 02H is the 8-bit value stored in the location 0A
|
112 |
|
|
SRAM[11]<= 8'b00000011; // 03H is the 8-bit value stored in the location 0B
|
113 |
|
|
SRAM[12]<= 8'b11111111; // Unused memory locations are filled with FF
|
114 |
|
|
SRAM[13]<= 8'b11111111; // Unused memory locations are filled with FF
|
115 |
|
|
SRAM[14]<= 8'b11111111; // Unused memory locations are filled with FF
|
116 |
|
|
SRAM[15]<= 8'b11111111; // Unused memory locations are filled with FF
|
117 |
|
|
end
|
118 |
|
|
endmodule
|
119 |
|
|
|
120 |
|
|
module IR_8(input clk, input rst , input LI,input EI,input [7:0] IR_IN,output [3:0] IR_OUT_1,output [3:0] IR_OUT_2);
|
121 |
|
|
reg [7:0] IR_r ; // General way of declaring a register datatype is : reg [DATA_WIDTH-1:0] reg_name [DEPTH-1:0] ; DEPTH - number of registers , DATA_WIDTH - Data occupancy capacity of each register. The DATA-WIDTH and DEPTH are required when creating a memory. Otherwise both of them are mutually optional
|
122 |
|
|
//reg [7:0] AR; // AR is a single register of 8-bit in width
|
123 |
|
|
// reg AR[7:0] ; // AR is a memory [group of 8 1-bit registers].
|
124 |
|
|
//reg [7:0] AR [7:0] ; // AR is a memory consisting of 8-registers , with each register capable of holding 8-bit value//
|
125 |
|
|
assign IR_OUT_1 = IR_r[7:4]; //Opcode or Instruction Field given to Controller or Sequencer
|
126 |
|
|
assign IR_OUT_2 = (~EI) ? IR_r[3:0] : 4'hZ; // Address Field of IR.
|
127 |
|
|
// Any component whose output is connected to a bus , must have a tristate input control associated with it. Only when the tristate input control is activated , the output must be available on the bus. Otherwise it must be tri-stated[All 1s which indicate neither Logic 0 nor Logic 1 voltage levels]
|
128 |
|
|
always@(posedge clk or posedge rst)
|
129 |
|
|
begin
|
130 |
|
|
if(rst)
|
131 |
|
|
IR_r <= 8'h00;
|
132 |
|
|
else if(~LI)
|
133 |
|
|
IR_r <= IR_IN;
|
134 |
|
|
end
|
135 |
|
|
endmodule
|
136 |
|
|
|
137 |
|
|
module RC_6(input clk,input NOP , input HLT , input rst , output [5:0] OUT); // Also called as ONE HOT-STATE COUNTER ; Generates 6 States.
|
138 |
|
|
reg [5:0] OUT_r;
|
139 |
|
|
integer i;
|
140 |
|
|
assign OUT = OUT_r;
|
141 |
|
|
always@(posedge clk or posedge rst)
|
142 |
|
|
begin
|
143 |
|
|
if(rst)
|
144 |
|
|
OUT_r <= 6'b000001;
|
145 |
|
|
else if(NOP)
|
146 |
|
|
OUT_r <= 6'b000001;
|
147 |
|
|
else if(HLT)
|
148 |
|
|
OUT_r <= 6'b000000;
|
149 |
|
|
else
|
150 |
|
|
begin
|
151 |
|
|
OUT_r[0] <= OUT_r[5];
|
152 |
|
|
// Most Significant bit or Left Most bit is 5 ; Least Significant bit or Right Most bit is 0 ; The 1[Hot State] travels from Left to Right. The content of Lsb is fed to Msb.
|
153 |
|
|
for(i = 0 ; i < 5 ; i = i + 1) // This for LOOP Travels from RIGHT MOST BIT to LEFT MOST BIT. During this process, the contents of a LEFT BIT[ at index "i+1"] is assigned to a RIGHT BIT[ at index i]
|
154 |
|
|
begin
|
155 |
|
|
OUT_r[i+1] <= OUT_r[i];
|
156 |
|
|
end
|
157 |
|
|
end
|
158 |
|
|
end
|
159 |
|
|
endmodule
|
160 |
|
|
|
161 |
|
|
module ID_8(input [3:0] INSTR , output LDA , output ADD , output SUB , output OUT , output HLT); // This is the Instruction Decoder Module. It receives the Instruction or Opcode Field from Instruction Register and Generates a control signal associated with a instruction//
|
162 |
|
|
assign LDA = ~INSTR[3] & ~INSTR[2] & ~INSTR[1] & ~INSTR[0]; //0000 is the opcode of LDA instruction.
|
163 |
|
|
assign ADD = ~INSTR[3] & ~INSTR[2] & ~INSTR[1] & INSTR[0]; //0001 is the opcode of ADD instruction.
|
164 |
|
|
assign SUB = ~INSTR[3] & ~INSTR[2] & INSTR[1] & ~INSTR[0]; //0010 is the opcode of SUB instruction.
|
165 |
|
|
assign OUT = INSTR[3] & INSTR[2] & INSTR[1] & ~INSTR[0]; //1110 is the opcode of OUT instruction.
|
166 |
|
|
assign HLT = INSTR[3] & INSTR[2] & INSTR[1] & INSTR[0]; //1111 is the opcode of HLT instruction.
|
167 |
|
|
endmodule
|
168 |
|
|
|
169 |
|
|
module CU_8(input LDA , input ADD , input SUB , input OUT , input [5:0] T , output CP , EP , LM , CE , LI , EI , LA , EA , SU , EU , LB , LO , NOP);
|
170 |
|
|
wire T1 , T2 , T3 , T4 , T5 , T6 ;
|
171 |
|
|
assign T1 = T[0];
|
172 |
|
|
assign T2 = T[1];
|
173 |
|
|
assign T3 = T[2];
|
174 |
|
|
assign T4 = T[3];
|
175 |
|
|
assign T5 = T[4];
|
176 |
|
|
assign T6 = T[5];
|
177 |
|
|
wire LDA_w , ADD_w , SUB_w , OUT_w;
|
178 |
|
|
assign LDA_w = LDA;
|
179 |
|
|
assign ADD_w = ADD;
|
180 |
|
|
assign SUB_w = SUB;
|
181 |
|
|
assign OUT_w = OUT;
|
182 |
|
|
assign CP = T2;
|
183 |
|
|
assign EP = T1;
|
184 |
|
|
assign LM = ~(T1 | (T4 & LDA_w) | (T4 & ADD_w) | (T4 & SUB_w));
|
185 |
|
|
assign CE = ~(T3 | (T5 & LDA_w) | (T5 & ADD_w) | (T5 & SUB_w));
|
186 |
|
|
assign LI = ~T3;
|
187 |
|
|
assign EI = ~((T4 & LDA_w) | (T4 & ADD_w) | (T4 & SUB_w));
|
188 |
|
|
assign LA = ~((T5 & LDA_w) | (T6 & ADD_w) | (T6 & SUB_w));
|
189 |
|
|
assign EA = T4 & OUT_w;
|
190 |
|
|
assign SU = T6 & SUB_w;
|
191 |
|
|
assign EU = (T6 & ADD_w) | (T6 & SUB_w);
|
192 |
|
|
assign LB = ~((T5 & ADD_w) | (T5 & SUB_w));
|
193 |
|
|
assign LO = ~(T4 & OUT_w);
|
194 |
|
|
assign NOP = (T6 & LDA_w) | (T6 & ADD_w) | (T6 & SUB_w) | (T5 & T6 & OUT_w);
|
195 |
|
|
endmodule
|
196 |
|
|
|
197 |
|
|
|
198 |
|
|
|
199 |
|
|
module ACC_8(input clk,input LA,input EA, input [7:0] ACC_IN,output [7:0] ACC_OUT_ALU , output [7:0] ACC_OUT_W_BUS);
|
200 |
|
|
reg [7:0] ACC_r;
|
201 |
|
|
assign ACC_OUT_ALU = ACC_r;
|
202 |
|
|
assign ACC_OUT_W_BUS = EA ? ACC_r : 8'hZZ;
|
203 |
|
|
always@(posedge clk) // Here clk and rst are asynchronous signals. When there is a single parameter in the sensitivity list of always block , the subsequent conditions are said to be synchronous to the single parameter mentioned in the sensitivity list. When there are multiple parameters separated by "or" keyword , then the parameters mentioned in the list are asynchronous with respect to each other//
|
204 |
|
|
begin
|
205 |
|
|
if(~LA)
|
206 |
|
|
ACC_r <= ACC_IN;
|
207 |
|
|
end
|
208 |
|
|
endmodule
|
209 |
|
|
|
210 |
|
|
|
211 |
|
|
module B_REG_1(input clk,input [7:0] DATA_IN,input LB,output [7:0] DATA_OUT);
|
212 |
|
|
reg [7:0] B_REG;
|
213 |
|
|
assign DATA_OUT = B_REG;
|
214 |
|
|
always@(posedge clk)
|
215 |
|
|
begin
|
216 |
|
|
if(~LB)
|
217 |
|
|
B_REG <= DATA_IN;
|
218 |
|
|
end
|
219 |
|
|
endmodule
|
220 |
|
|
|
221 |
|
|
module ALU8_1(input [7:0] A,input [7:0] B, input SU,input EU , output [7:0] ALU_OUT);
|
222 |
|
|
wire [7:0] ALU_OUT_w = SU ? A-B : A+B; //Let X be a variable ; Prefixing a -(minus symbol) to a variable is equivalent to taking 2's complement of the variable.
|
223 |
|
|
assign ALU_OUT = EU ? ALU_OUT_w : 8'h00;
|
224 |
|
|
endmodule
|
225 |
|
|
|
226 |
|
|
module OR_1(input clk , input [7:0] DATA_IN , input LO , output [7:0] DATA_OUT);
|
227 |
|
|
reg [7:0] OR_r;
|
228 |
|
|
assign DATA_OUT = OR_r;
|
229 |
|
|
always@(posedge clk)
|
230 |
|
|
begin
|
231 |
|
|
if(~LO)
|
232 |
|
|
OR_r <= DATA_IN;
|
233 |
|
|
end
|
234 |
|
|
endmodule
|