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