1 /*****************************************************************************
2
3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4 more contributor license agreements. See the NOTICE file distributed
5 with this work for additional information regarding copyright ownership.
6 Accellera licenses this file to you under the Apache License, Version 2.0
7 (the "License"); you may not use this file except in compliance with the
8 License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 implied. See the License for the specific language governing
16 permissions and limitations under the License.
17
18 *****************************************************************************/
19
20 /*****************************************************************************
21
22 main -- This is a simple CPU modeling using SystemC.
23 Architecure defined by Martin Wang.
24 You can initialize register by modifying file
25 named register, and so is bios, and dacache.
26
27 Original Author: Martin Wang, Synopsys, Inc.
28
29 *****************************************************************************/
30
31 /*****************************************************************************
32
33 MODIFICATION LOG - modifiers, enter your name, affiliation, date and
34 changes you are making here.
35
36 Name, Affiliation, Date:
37 Description of Modification:
38
39 *****************************************************************************/
40
41
42 #include "directive.h"
43 #include "systemc.h"
44 #include "bios.h"
45 #include "paging.h"
46 #include "icache.h"
47 #include "fetch.h"
48 #include "decode.h"
49 #include "exec.h"
50 #include "mmxu.h"
51 #include "floating.h"
52 #include "dcache.h"
53 #include "pic.h"
54 #include <climits>
55 #include <cstdlib>
56 #include <time.h>
57 //#include <sys/times.h>
58 #include <limits.h>
59
sc_main(int,char * [])60 int sc_main(int, char *[])
61 {
62 // Silence the following deprecation warning:
63 // Info: (I804) /IEEE_Std_1666/deprecated: positional binding
64 // using << or , is deprecated, use () instead.
65
66
67 sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING);
68 static const sc_writer_policy mw = SC_MANY_WRITERS;
69
70 // ************************ ICACHE ***********************************
71 // ICACHE = ram_cs
72 // ICACHE = ram_we
73 // ICACHE = addr
74 // ICACHE = ram_datain
75 // ICACHE = ram_dataout
76 // ICACHE = ld_valid = pid_valid
77 // ICACHE = ld_data = pid_data
78 sc_signal<bool> icache_valid("ICACHE_VALID") ;
79
80 // ************************ BIOS ***********************************
81 sc_signal<bool> ram_cs("RAM_CS") ;
82 sc_signal<bool> ram_we("RAM_WE") ;
83 sc_signal<unsigned> addr("Address") ;
84 sc_signal<unsigned> ram_datain("RAM_DATAIN") ;
85 sc_signal<unsigned,mw> ram_dataout("RAM_DATAOUT") ;
86 sc_signal<bool> bios_valid("BIOS_VALID") ;
87 const int delay_cycles = 2;
88
89 // ************************ Paging ***********************************
90 // Paging paging_din = ram_datain
91 // Paging paging_csin = ram_cs
92 // Paging paging_wein = ram_we
93 // Paging logical_address = addr
94 sc_signal<unsigned> icache_din("ICACHE_DIN") ;
95 sc_signal<bool> icache_validin("ICACHE_VALIDIN") ;
96 sc_signal<bool> icache_stall("ICACHE_STALL") ;
97 sc_signal<unsigned> paging_dout("PAGING_DOUT") ;
98 sc_signal<bool> paging_csout("PAGING_CSOUT") ;
99 sc_signal<bool> paging_weout("PAGING_WEOUT") ;
100 sc_signal<unsigned> physical_address("PHYSICAL_ADDRESS") ;
101 // Paging dataout = ram_dataout
102 // Paging data_valid = icache_valid
103 // Paging stall_ifu = stall_fetch
104
105
106 // ************************ Fetch ***********************************
107 // IFU ramdata = ram_dataout
108 sc_signal<unsigned> branch_target_address("BRANCH_TARGET_ADDRESS") ;
109 sc_signal<bool> next_pc("NEXT_PC") ;
110 sc_signal<bool> branch_valid("BRANCH_VALID") ;
111 sc_signal<bool,mw> stall_fetch("STALL_FETCH") ;
112 sc_signal<bool> pred_fetch("PRED_FETCH") ;
113 // IFU ram_valid = bios_valid
114 // IFU ram_cs = ram_cs
115 // IFU ram_we = ram_we
116 // IFU address = addr
117 // IFU smc_instrction = ram_datain
118 // IFU pred_branch_address = pred_branch_address
119 // IFU pred_branch_valid = pred_branch_valid
120 sc_signal<unsigned> instruction("INSTRUCTION") ;
121 sc_signal<bool> instruction_valid("INSTRUCTION_VALID") ;
122 sc_signal<unsigned> program_counter("PROGRAM_COUNTER") ;
123 sc_signal<bool> branch_clear("BRANCH_CLEAR") ;
124 sc_signal<bool> pred_fetch_valid("PRED_FETCH_VALID") ;
125 sc_signal<bool> reset("RESET") ;
126
127 // ************************ Branch ***********************************
128 // BPU: fetch_inst = instruction
129 // BPU: fetch_pc = program_counter
130 // BPU: fetch_valid = instruction_valid
131 // BPU: branch_inst_addr = branch_instruction_address
132 // BPU: branch_target_address = branch_target_address
133 // BPU: branch_valid = branch_valid
134 sc_signal<unsigned > pred_branch_address("PRED_BRANCH_ADDRESS");
135 sc_signal<bool> pred_branch_valid("PRED_BRANCH_VALID") ;
136 sc_signal<bool> pred_tellid("PRED_TELLID") ;
137 sc_signal<unsigned> pred_instruction("PRED_INSTRUCTION") ;
138 sc_signal<bool> pred_inst_valid("PRED_INST_VALID") ;
139 sc_signal<unsigned > pred_inst_pc("PRED_INST_PC");
140
141
142 // ************************ Decode ***********************************
143 // ID instruction = instruction
144 // ID instruction = instruction_valid
145 // ID destreg_write = out_valid
146 // ID destreg_write_src = destout
147 // ID clear_branch = branch_clear
148 // ID pc = program_counter
149 sc_signal<bool> pred_on("PRED_ON") ;
150 sc_signal<unsigned> branch_instruction_address("BR_INSTRUCTION_ADDRESS");
151 // ID alu_dataout = dout from EXEC
152 sc_signal<signed> dram_dataout("DRAM_DATAOUT") ;
153 sc_signal<bool> dram_rd_valid("DRAM_RD_VALID") ;
154 sc_signal<unsigned> dram_write_src("DRAM_WRITE_SRC");
155 // ID next_pc = next_pc
156 // ID branch_valid = branch_valid
157 // ID branch_target_address = branch_target_address
158 sc_signal<bool> mem_access("MEM_ACCESS") ;
159 sc_signal<unsigned> mem_address("MEM_ADDRESS") ;
160 sc_signal<int> alu_op("ALU_OP") ;
161 sc_signal<bool> mem_write("MEM_WRITE") ;
162 sc_signal<unsigned> alu_src("ALU_SRC") ;
163 sc_signal<bool> reg_write("REG_WRITE") ;
164 sc_signal<signed int> src_A("SRC_A") ;
165 sc_signal<signed int> src_B("SRC_B") ;
166 sc_signal<bool> forward_A("FORWARD_A") ;
167 sc_signal<bool> forward_B("FORWARD_B") ;
168 // ID stall_fetch = stall_fetch
169 sc_signal<bool> decode_valid("DECODE_VALID") ;
170 sc_signal<bool> float_valid("FLOAT_VALID") ;
171 sc_signal<bool> mmx_valid("MMX_VALID") ;
172 sc_signal<bool> pid_valid("PID_VALID") ;
173 sc_signal<signed> pid_data("PID_DATA") ;
174
175 // ************************ DCACHE ***********************************
176 sc_signal<signed> mmic_datain("MMIC_DATAIN") ; /* DCU: datain */
177 sc_signal<unsigned> mmic_statein("MMIC_STATEIN") ;/* DCU: statein */
178 sc_signal<bool> mmic_cs("MMIC_CS") ; /* DCU: cs */
179 sc_signal<bool> mmic_we("MMIC_WE") ; /* DCU: we */
180 sc_signal<unsigned> mmic_addr("MMIC_ADDR") ; /* DCU: addr */
181 sc_signal<unsigned> mmic_dest("MMIC_DEST") ; /* DCU: dest */
182 sc_signal<unsigned> mmic_destout("MMIC_DESTOUT") ;/* DCU: destout */
183 sc_signal<signed> mmic_dataout("MMIC_DATAOUT") ;/* DCU: dataout */
184 sc_signal<bool> mmic_out_valid("MMIC_OUT_VALID") ;/* DCU: out_valid*/
185 sc_signal<unsigned> mmic_stateout("MMIC_STATEOUT") ;/* DCU: stateout */
186
187 // ************************ Execute ***********************************
188 // EXEC in_valid = decode_valid
189 sc_signal<bool> in_valid("IN_VALID") ;
190 // EXEC opcode = alu_op
191 sc_signal<bool> negate("NEGATE") ;
192 sc_signal<int> add1("ADD1") ;
193 sc_signal<bool> shift_sel("SHIFT_SEL") ;
194 // EXEC dina = src_A
195 // EXEC dinb = src_B
196 // EXEC dest = alu_src
197 sc_signal<bool> c("C") ;
198 sc_signal<bool> v("V") ;
199 sc_signal<bool> z("Z") ;
200 sc_signal<signed> dout("DOUT") ;
201 sc_signal<bool> out_valid("OUTPUT_VALID") ;
202 sc_signal<unsigned> destout("DESTOUT") ;
203
204 // ************************ Floating point ******************************
205 // FPU in_valid = float_valid
206 // FPU opcode = alu_op
207 // FPU floata = src_A
208 // FPU floatb = src_B
209 // FPU dest = alu_src
210 sc_signal<signed,mw> fdout("FDOUT") ;
211 sc_signal<bool,mw> fout_valid("FOUT_VALID") ;
212 sc_signal<unsigned,mw> fdestout("FDESTOUT") ;
213
214 // ************************ PIC *****************************************
215 sc_signal<bool> ireq0("IREQ0") ;
216 sc_signal<bool> ireq1("IREQ1") ;
217 sc_signal<bool> ireq2("IREQ2") ;
218 sc_signal<bool> ireq3("IREQ3") ;
219 // PIC cs = interrupt_ack
220 // PIC intack_cpu = interrupt_ack
221 sc_signal<bool> rd_wr("RD_WR") ;
222 sc_signal<bool> intreq("INTREQ") ;
223 sc_signal<unsigned> vectno("VECTNO") ;
224 sc_signal<bool> intack("INTACK") ;
225 sc_signal<bool> intack_cpu("INTACK_CPU") ;
226
227 // ************************ MMX ***********************************
228 // MMX mmx_valid = mmx_valid
229 // MMX opcode = alu_op
230 // MMX mmxa = src_A
231 // MMX mmxb = src_B
232 // MMX dest = dest
233 // MMX mmxdout = fdout
234 // MMX mmxout_valid = fpu_valid
235 // MMX mmxdestout = fpu_destout
236
237 // ************************ DSP *****************************************
238 sc_signal<int> dsp_in1("DPS_IN1");
239 sc_signal<int> dsp_out1("DSP_OUT1");
240 sc_signal<bool> dsp_data_valid("DSP_DATA_VALID");
241 sc_signal<bool> dsp_input_valid("DSP_INPUT_VALID");
242 sc_signal<bool> dsp_data_requested("DSP_DATA_REQUESTED");
243
244 ////////////////////////////////////////////////////////////////////////////
245 // MAIN PROGRAM
246 ////////////////////////////////////////////////////////////////////////////
247 sc_clock clk("Clock", 1, SC_NS, 0.5, 0.0, SC_NS);
248
249 printf("/////////////////////////////////////////////////////////////////////////\n");
250 printf("// This code is written at SYNOPSYS, Inc.\n");
251 printf("/////////////////////////////////////////////////////////////////////////\n");
252 printf("// Module : main of CPU Model\n");
253 printf("// Author : Martin Wang\n");
254 printf("// Company : SYNOPSYS, Inc.\n");
255 printf("// Purpose : This is a simple CPU modeling using SystemC.\n");
256 printf("// Instruction Set Architecure defined by Martin Wang.\n");
257 printf("// \n");
258 printf("// SystemC (TM) Copyright (c) 1988-2014 by Synopsys, Inc. \n");
259 printf("// \n");
260 printf("/////////////////////////////////////////////////////////////////////////\n");
261 cout << "// IN THIS MACHINE Integer is " << sizeof (int) << " bytes.\n";
262 cout << "// IN THIS MACHINE Floating is " << sizeof (float) << " bytes.\n";
263 cout << "// IN THIS MACHINE Double is " << sizeof (double) << " bytes.\n";
264 printf("// \n");
265 printf("// \n");
266 printf("// .,,uod8B8bou,,.\n");
267 printf("// ..,uod8BBBBBBBBBBBBBBBBRPFT?l!i:.\n");
268 printf("// ,=m8BBBBBBBBBBBBBBBRPFT?!||||||||||||||\n");
269 printf("// !...:!TVBBBRPFT||||||||||!!^^\"\" ||||\n");
270 printf("// !.......:!?|||||!!^^\"\"' ||||\n");
271 printf("// !.........|||| ### # # ||||\n");
272 printf("// !.........|||| ### # # # # ||||\n");
273 printf("// !.........|||| # # # # # ||||\n");
274 printf("// !.........|||| # # # # # ||||\n");
275 printf("// !.........|||| # ## # # ||||\n");
276 printf("// !.........|||| # # ### ||||\n");
277 printf("// `.........|||| # # # ,||||\n");
278 printf("// .;.......|||| ### _.-!!|||||\n");
279 printf("// .,uodWBBBBb.....|||| _.-!!|||||||||!:'\n");
280 printf("// !YBBBBBBBBBBBBBBb..!|||:..-!!|||||||!iof68BBBBBb....\n");
281 printf("// !..YBBBBBBBBBBBBBBb!!||||||||!iof68BBBBBBRPFT?!:: `.\n");
282 printf("// !....YBBBBBBBBBBBBBBbaaitf68BBBBBBRPFT?!::::::::: `.\n");
283 printf("// !......YBBBBBBBBBBBBBBBBBBBRPFT?!::::::;:!^\"`;::: `.\n");
284 printf("// !........YBBBBBBBBBBRPFT?!::::::::::^''...::::::; iBBbo.\n");
285 printf("// `..........YBRPFT?!::::::::::::::::::::::::;iof68bo. WBBBBbo.\n");
286 printf("// `..........:::::::::::::::::::::::;iof688888888888b. `YBBBP^'\n");
287 printf("// `........::88::::::::::::;iof688888888888888888888b. `\n");
288 printf("// `......::81:::::;iof688888888888888888888888888888b.\n");
289 printf("// `....:::;iof688888888888888888888888888888888899fT!\n");
290 printf("// `..::!8888888888888888888888888888888899fT|!^\"'\n");
291 printf("// `' !!988888888888888888888888899fT|!^\"'\n");
292 printf("// `!!8888888888888888899fT|!^\"'\n");
293 printf("// `!988888888899fT|!^\"'\n");
294 printf("// `!9899fT|!^\"'\n");
295 printf("// `!^\"'\n");
296 printf("// \n");
297 printf("// \n");
298 printf("/////////////////////////////////////////////////////////////////////////\n\n\n");
299
300
301 fetch IFU("FETCH_BLOCK");
302 IFU.init_param(delay_cycles);
303 IFU << ram_dataout << branch_target_address << next_pc << branch_valid
304 << stall_fetch << intreq << vectno << bios_valid << icache_valid
305 << pred_fetch << pred_branch_address << pred_branch_valid << ram_cs << ram_we
306 << addr << ram_datain << instruction << instruction_valid << program_counter
307 << intack_cpu << branch_clear << pred_fetch_valid << reset << clk;
308
309 decode IDU("DECODE_BLOCK");
310 IDU << reset << instruction << pred_instruction << instruction_valid
311 << pred_inst_valid << out_valid << destout << dout << dram_dataout
312 << dram_rd_valid << destout << fdout << fout_valid << fdestout
313 << branch_clear << dsp_data_valid << program_counter << pred_on
314 << branch_instruction_address << next_pc << branch_valid
315 << branch_target_address << mem_access << mem_address << alu_op
316 << mem_write << alu_src << reg_write << src_A << src_B << forward_A
317 << forward_B << stall_fetch << decode_valid << float_valid << mmx_valid
318 << pid_valid << pid_data << clk;
319
320 exec IEU("EXEC_BLOCK");
321 IEU << reset << decode_valid << alu_op << negate << add1 << shift_sel
322 << src_A << src_B << forward_A << forward_B << alu_src << c << v << z
323 << dout << out_valid << destout << clk;
324
325 floating FPU("FLOAT_BLOCK"); // order dependent
326 FPU << float_valid << alu_op << src_A << src_B << alu_src
327 << fdout << fout_valid << fdestout << clk;
328
329 mmxu MMXU("MMX_BLOCK");
330 MMXU << mmx_valid << alu_op << src_A << src_B << alu_src
331 << fdout << fout_valid << fdestout << clk;
332
333 bios BIOS("BIOS_BLOCK");
334 BIOS.init_param(delay_cycles);
335 BIOS.datain(ram_datain); // order independent
336 BIOS.cs(ram_cs);
337 BIOS.we(ram_we);
338 BIOS.addr(addr);
339 BIOS.dataout(ram_dataout);
340 BIOS.bios_valid(bios_valid);
341 BIOS.stall_fetch(stall_fetch);
342 BIOS.CLK(clk);
343
344 paging PAGING("PAGING_BLOCK");
345 PAGING << ram_datain << ram_cs << ram_we << addr << icache_din
346 << icache_validin << icache_stall << paging_dout << paging_csout
347 << paging_weout << physical_address << ram_dataout << icache_valid
348 << stall_fetch << clk ;
349
350 icache ICACHE("ICACHE_BLOCK");
351 ICACHE.init_param(delay_cycles);
352 ICACHE << paging_dout << paging_csout << paging_weout
353 << physical_address << pid_valid << pid_data << icache_din << icache_validin
354 << icache_stall << clk;
355
356 dcache DCACHE("DCACHE_BLOCK");
357 DCACHE.init_param(delay_cycles);
358 DCACHE << mmic_datain << mmic_statein << mmic_cs << mmic_we << mmic_addr
359 << mmic_dest << mmic_destout << mmic_dataout << mmic_out_valid << mmic_stateout << clk;
360
361 pic APIC("PIC_BLOCK");
362 APIC << ireq0 << ireq1 << ireq2 << ireq3 <<intack_cpu << rd_wr
363 << intack_cpu << intreq << intack << vectno;
364
365 time_t tbuffer = time(NULL);
366
367 sc_start();
368
369 cout << "Time for simulation = " << (time(NULL) - tbuffer) << endl;
370
371 return 0; /* this is necessary */
372 }
373