SystemC 2.0 CPU CPU CTD&SW CT-PF 2002/1/23 1
CPU BCA UTF GenericCPU IO (sc_main) 2002/1/23 2
CPU CPU CQ 1997 11 Page 207 4 Perl Verilog-HDL CPU / Verilog-HDL SystemC 2.0 (asm) ROM (test.hex) 2002/1/23 3
init GenericCPU reset Top TestBench nrst ROM ROM CLK fetch decode execute load IO store load store dump 2002/1/23 4
BCA UTF BCA UTF GenericCPU IO GenericCPU IO CLK Addr CLK ncs Ready noe Data Addr Data nwe Data Addr Data 7CLK 0 2002/1/23 5
GenericCPU init GenericCPU reset 1) (init ) 2) ( reset ) 3) ( clock_posedge ) ( fetch ) ( decode ) ( execute ) ( load ( store ) 4) ( dumpreg ) ROM ROM fetch decode execute dump load store 2002/1/23 6
(GenericCPU GenericCPU.hpp ) #include <string> #include "systemc.h" class GenericCPU : public sc_module private : static const int MEM_SIZE = 1024; string hex_file; bool dump; int memory[mem_size]; int Reg[8]; int pc, eq, lt, gt; int code, r0, r1, imm; void clock_posedge( void ); public : SC_HAS_PROCESS(GenericCPU); GenericCPU(sc_module_name name, char *_hex_file = "test.hex", bool _dump = true) : sc_module(name), hex_file(_hex_file), dump(_dump) SC_CTHREAD(clock_posedge, CLK.pos()); watching(nrst.delayed() == false); init(); void init( void ); void reset( void ); int fetch( int p ); void decode( int decode ); void execute( void ); void dumpreg( void ); void load( int addr, int& data ); void store( int addr, int data ); int readmem( const char *file, int *mem, int size ); int analyze_buffer( char *buffer, int *val); 2002/1/23 7
(GenericCPU GenericCPU.hpp ) BCA UTF #include sc_mslib.h // sc_inoutmaster private : private : static const bool LOGIC_0 = false; static const bool LOGIC_1 = true; static const char *const HiZ_32 = "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; inline void high_cs( void ) ncs = LOGIC_1; inline void low_cs( void ) ncs = LOGIC_0; inline void high_oe( void ) noe = LOGIC_1; inline void low_oe( void ) noe = LOGIC_0; inline void high_we( void ) nwe = LOGIC_1; inline void low_we( void ) nwe = LOGIC_0; inline void hiz_a( void ) A = HiZ_32; inline void set_a( const int val ) A = val; inline void hiz_d( void ) D = HiZ_32; inline void set_d( const int val ) D = val; inline int get_d( void ) sc_uint<32> sig; sig = D; return((int)sig); public : sc_out_rv<32> A; sc_inout_rv<32> D; sc_out<bool> ncs; sc_out<bool> noe; sc_out<bool> nwe; sc_in<bool> READY; public : sc_inoutmaster<int, sc_indexed<int,1024> > MP; 2002/1/23 8
(GenericCPU GenericCPU.cpp : ) void GenericCPU::init( void ) if( readmem( hex_file.c_str(), memory, MEM_SIZE ) ) exit(1); void GenericCPU::clock_posedge( void ) if( nrst.read() == false ) /* Reset */ reset(); while(true) wait(); decode( fetch(pc) ); execute(); void GenericCPU::decode( int decode ) code = (decode >> 24) & 0x000000ff; r0 = (decode >> 20) & 0x0000000f; r1 = (decode >> 16) & 0x0000000f; imm = decode & 0x0000ffff; printf("pc = %08x CODE = 0x%02x R0 = %d R1 = %d IMM = 0x%04x n", pc, code, r0, r1, imm ); void GenericCPU::dumpreg( void ) inti, tmp; printf( "Register Contents t t t trom Contents n" ); if( dump ) dumpreg(); for( i=0 ; i<8 ; i=i+1 ) tmp = i+pc-3; tmp = tmp < 0? 0 : tmp; int GenericCPU::fetch( int p ) return memory[p]; printf("reg[ %d] : %08x t trom[%08x]=%08x n", i, Reg[i], tmp, memory[tmp] ) ; 2002/1/23 9
(GenericCPU.cpp ) void GenericCPU::execute( void ) int jmp = 1; switch(code) case CPU_ADD : Reg[r0] = Reg[r0] + Reg[r1]; break; case CPU_SUB : Reg[r0] = Reg[r0] - Reg[r1]; break; case CPU_MOV : Reg[r0] = Reg[r1]; break; case CPU_SETHI : Reg[r0] = ( MASK_HI(imm<<16) MASK_LO(Reg[r0]) ); break; case CPU_SETLO : Reg[r0] = ( MASK_HI(Reg[r0]) MASK_LO(imm) ); break; case CPU_CMP : if( Reg[r0] == Reg[r1] ) eq = 1, gt = 0, lt = 0; else if( Reg[r0] > Reg[r1] ) eq = 0, gt = 1, lt = 0; else if( Reg[r0] < Reg[r1] ) eq = 0, gt = 0, lt = 1; break; case CPU_JMP : jmp = SET_JUMP(imm); break; case CPU_JEQ : if( eq ) jmp = SET_JUMP(imm); break; case CPU_JGT : if( gt ) case CPU_JLT : if( lt ) jmp = SET_JUMP(imm); break; jmp = SET_JUMP(imm); break; case CPU_LOAD : load(reg[r0], Reg[r1]); break; case CPU_STORE : store(reg[r0], Reg[r1]); break; case CPU_HALT : printf("generic CPU Model : halt n"); sc_stop(); break; case CPU_FINISH : printf("generic CPU Model : exit at %f n", sc_simulation_time()); exit(0); break; default : printf("error : Generic CPU Model does not support Code 0x%02x n", code); break; Reg[0] = 0; pc = pc + jmp; 2002/1/23 10
(GenericCPU GenericCPU.cpp ) BCA void GenericCPU::reset( void ) high_cs(); high_oe(); high_we(); hiz_a(); hiz_d(); UTF void GenericCPU::reset( void ) // BCA // for(int i=0 ; i<8 ; i++) Reg[i] = 0; pc = 0; eq = 0; lt = 0; gt = 0; code = 0; r0 = 0; r1 = 0; imm = 0; // for(int i=0 ; i<8 ; i++) Reg[i] = 0; pc = 0; eq = 0; lt = 0; gt = 0; code = 0; r0 = 0; r1 = 0; imm = 0; 2002/1/23 11
(GenericCPU GenericCPU.cpp ) BCA void GenericCPU::load( int addr, int &data ) set_a(addr); wait(); low_cs(); wait(); low_oe(); UTF void GenericCPU::load( int addr, int &data ) data = MP[addr]; // while(true) wait(); if( READY.read() == LOGIC_1 ) data = get_d(); // break; wait(); high_oe(); high_cs(); wait(); hiz_a(); 2002/1/23 12
(GenericCPU GenericCPU.cpp ) BCA void GenericCPU::store( int addr, int data ) set_d(data); // set_a(addr); UTF void GenericCPU::store( int addr, int data ) MP[addr] = data; // wait(); low_cs(); wait(); low_we(); while(true) wait(); if( READY.read() == LOGIC_1 ) high_we(); break; wait(); hiz_d(); high_cs(); wait(); hiz_a(); 2002/1/23 13
IO GenericCPU / IO GenericCPU load store (mem) 2002/1/23 14
(BCA BCA IO. IO.hpp) #include "systemc.h" SC_MODULE(IO) ; private : static const int MEM_SIZE = 1024; int memory[mem_size]; void clock_posedge( void ); public : sc_in_clk CLK; sc_in<bool> nrst; sc_in_rv<32> A; sc_inout_rv<32> D; sc_in<bool> ncs; sc_in<bool> noe; sc_in<bool> nwe; sc_out<bool> READY; SC_CTOR(IO) SC_CTHREAD(clock_posedge, CLK.pos()); watching(nrst.delayed() == false); void IO::clock_posedge( void ) if( nrst.read() == false ) /* Reset */ READY = false; D = "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; while(true) wait_until( ncs.delayed() == false); wait(); /* Clock */ if( noe.read() == false ) /* Read */ sc_uint<32> sig_a; sig_a = A.read(); D.write(memory[sig_a]); wait(); /* Clock */ if( nwe.read() == false ) /* Write */ sc_uint<32> sig_a, sig_d; sig_a = A.read(); sig_d = D.read(); memory[sig_a] = sig_d; READY.write(true); do wait(); /* Clock */ READY.write(false); while ( ncs.read() == false ); D.write("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"); 2002/1/23 15
(UTF UTF IO. IO.hpp) #include "systemc.h" #include sc_mslib.h // sc_inoutslave void IO::io_access( void ) int addr = SP.get_address(); SC_MODULE(IO) private: static const int MEM_SIZE = 1024; int memory[mem_size]; void io_access( void ); if( SP.input() ) memory[addr] = SP; else SP = memory[addr]; // Write // Read public: // sc_inoutslave<int, sc_indexed<int,1024> > SP; ; SC_CTOR(IO) SC_SLAVE(io_access, SP); 2002/1/23 16
(sc_main sc_main) sc_main GenericCPU cpu("genericcpu", file, dump); IO IO io("io"); GenericCPU IO sc_signal<bool> nrst; nrst CLK sc_clock CLK("CLK", 20, SC_NS, 0.5, 0.0, SC_NS, true); 2002/1/23 17
(BCA BCA main. main.cpp) #include "systemc.h" #include "GenericCPU.hpp" #include "IO.hpp" int sc_main(int argc, char *argv[]) sc_signal<bool> nrst; sc_signal<bool> READY; sc_signal_rv<32> A; sc_signal_rv<32> D; sc_signal<bool> ncs; sc_signal<bool> noe; sc_signal<bool> nwe; // sc_clock CLK("CLK", 20, SC_NS, 0.5, 0.0, SC_NS, true); // GenericCPU GenericCPU cpu.clk(clk); cpu.nrst(nrst); cpu.a(a); cpu.d(d); cpu.ncs(ncs); cpu.noe(noe); cpu.nwe(nwe); cpu.ready(ready); cpu("genericcpu", file, dump); // IO IO io("io"); io.clk(clk); io.nrst(nrst); io.a(a); io.d(d); io.ncs(ncs); io.noe(noe); io.nwe(nwe); io.ready(ready); // nrst = false; sc_start(40, SC_NS); nrst = true; sc_start(-1); return 0; /* this is necessary */ 2002/1/23 18
(UTF UTF main. main.cpp) #include "systemc.h" // IO #include "GenericCPU.hpp" #include "IO.hpp" int sc_main(int argc, char *argv[]) sc_signal<bool> nrst; sc_link_mp<int> PORT; IO io("io"); // io.sp(port); // sc_clock CLK("CLK", 20, SC_NS, 0.5, 0.0, SC_NS, true); // GenericCPU GenericCPU cpu.clk(clk); cpu.nrst(nrst); cpu.mp(port); cpu("genericcpu", file, dump); // nrst = false; sc_start(40, SC_NS); nrst = true; sc_start(-1); return 0; /* this is necessary */ 2002/1/23 19
(VCD ) WaveViewer GtkWave(Unix) GtkWave(Win32) Dinotrace http://www.syncad.com/ http://daggit.pagecreator.com/ver/wave/ http://www.geocities.com:0080/siliconvalley/ Campus/3216/GTKWave/gtkwave-win32.html http://www.ultranet.com/~wsnyder/veripool/dinotrace/ Viewer sc_trace_file *trace_file = sc_create_vcd_trace_file("genericcpu"); sc_trace(trace_file, CLK, "CLK"); sc_trace(trace_file, nrst, "nrst"); 2002/1/23 20
Behavior/Interface/Channel GenericCPU IO Core (Behavior) I/F Channel I/F Core (Function) Inheritance( ) GenericCPU Core Interface 2002/1/23 21
SystemC 2.0 (PC/Linux Sun/Solaris PC/Windows ) C++ ( ) Behavior/Interface/Channel SystemC 2.0 (Bug ) ( ) ( ) ( )! PC/Windows C++ 2002/1/23 22