Thông báo

Collapse
No announcement yet.

Tutorial : Căn bản về systemC để mô hình phần cứng

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Tutorial : Căn bản về systemC để mô hình phần cứng

    Trước hết các bạn nào muốn học hỏi về đề tài này, cần phải có:

    1) Căn bản về RTL (VHDL hoặc Verilog)
    2) Cài IDE cho C/C++, down link ở dưới
    http://www.brothersoft.com/visual-c+...oad-65282.html
    3) Theo link dưới đây để setup cho systemC
    http://www.dientuvietnam.net/forums/...ad.php?t=34506
    4) Căn bản về C/C++ (OOP thì càng tốt)

    Tutorial này sẽ chia ra làm nhiều bước, mong các bạn đón xem và cho ý kiến.

    Tôi có một yêu cầu là MỌI CÂU HỔI xin vui lòng PM cho tôi để tránh làm lạc đề của tutorial này. Tôi sẽ cố gắng nêu ra vấn đề từ những câu hỏi đó trong quá trình của tutorial để mọi người tham khảo thêm. Để học hỏi sâu về tutorial này, tôi khuyên các bạn cố gắng đặt phần mềm visual C/C++, theo chỉ dẫn để setup systemC kit và chạy thử với cái ví dụ đính kèm vì tutorial này sẽ tạo điều kiện thực tập. Các bạn có thể PM cho tôi biết khi các bạn đã sẵn sàng

    Tony
    Last edited by tonyvandinh; 10-04-2010, 04:42.
    Chúc một ngày vui vẻ
    Tony
    email : dientu_vip@yahoo.com

  • #2
    Trước hết tôi xin làm trên một ví dụ rất đơn giản mà ai đã làm về RTL đều biết: 4 bit counter.

    1) Counter có reset để trở lại zero (0)
    2) Counter có thể ngừng và tiếp tục đếm
    3) Đếm từ 0 tới 15 rồi trở lại 0.

    Dưới đây là code viết theo mã Verilog

    Code:
    module vcounter(clock, reset, enable, count_out);
    	input clock, reset, enable;
    	output [3:0] count_out;
    	reg [3:0] count_out;
    	
    	always @(posedge clock, reset)
    	begin
    		if (reset)
    			count_out = 4'b0000;
    		else if (enable)
    			count_out = count_out + 1'b1;
    	end
    endmodule
    Các bạn sẽ có thể nói là "anh chàng này vớ vẩn thiệt, đã làm được ở VHDL/Verilog rồi thì dùng systemC để làm gì?". Tôi xin tạm khoan trả lời và hy vọng sẽ nêu ra những lợi và khuyết điểm trong quá trình của tutorial này.

    Dưới đây là C/C++ code cho cùng một hoạt động với khối verilog trên

    Code:
    int counter(bool *reset, bool *enable)
    {
    	int static count = 0;
    	
    	if (*reset)
    		count = 0;
    	else if (*enable)
    	{
    		if (count == 15)
    			count = 0;
    		else
    			count++;
    	}
    		
    	return count;
    }
    Nếu muốn chạy thử khối Verilog, các bạn cần phải có một công cụ gọi là simulator. Công cụ này thường thì được viết bằng C/C++ để dịch biến trạng thái hoạt động của RTL. Còn nếu muốn chạy ở khối C/C++, thì bạn có thể trực tiếp compile và chạy thẳng trên máy chủ không cần một công cụ nào hết. Vậy thì khối nào sẽ chạy nhanh hơn? Chắc các bạn đã có câu trả lời :-)

    Nhưng mà khối verilog có xung và hiện nay có công cụ tổng hợp để chuyển qua phần cứng, còn khối C? Chắc chắn các bạn sẽ có thắc mắc này và cũng như truyện Kim Dung, tôi xin hẹn các bạn ở bước kế :-)

    Chào
    Tony
    Last edited by tonyvandinh; 10-04-2010, 04:49.
    Chúc một ngày vui vẻ
    Tony
    email : dientu_vip@yahoo.com

    Comment


    • #3
      Thử nghiệm - test bench

      Để thử nghiệm, dưới đây là test bench cho khối C/C++

      Code:
      #include "stdio.h"
      #define TIME
      #define PERIOD 10
      
      void my_print(int &count, int &tnow)
      {
      	#ifdef TIME
      	printf("at %d ns; count = %d\n", tnow, count);
      	#else
      	printf("count = %d\n", count);
      	#endif
      }
      
      int main()
      {
      	bool reset, enable;
      	
      	// Reset
      	reset = 1;
      	enable = 0;
      	int count;
      	int tnow = 0;
      	
      	printf("Reset phase\n");
      	count = counter(&reset, &enable);
      	my_print(count, tnow);
      	tnow += PERIOD;
      	
      	// Release reset
      	reset = 0;
      	printf("Disable Phase\n");
      	
      	for (int i=0; i<4; i++)
      	{
      		count = counter(&reset, &enable);
      		my_print(count, tnow);
      		tnow += PERIOD;
      	}
      	
      	// Enable counter
      	enable = 1;
      	printf("Counter Starts, count 4 times\n");
      	
      	for (int i=0; i<4; i++)
      	{
      		count = counter(&reset, &enable);
      		my_print(count, tnow);
      		tnow += PERIOD;
      	}
      
      	// Disable counter
      	enable = 0;
      	printf("Counter Stops, 4 times\n");
      	
      	for (int i=0; i<4; i++)
      	{
      		count = counter(&reset, &enable);
      		my_print(count, tnow);
      		tnow += PERIOD;
      	}
      
      	// Enable counter
      	enable = 1;
      	printf("Counter continues until it wraps over\n");
      	
      	for (int i=0; i<16; i++)
      	{
      		count = counter(&reset, &enable);
      		my_print(count, tnow);
      		tnow += PERIOD;
      	}
      
      	return(0);
      }
      Kết qua khi không đinh nghĩa TIME

      Reset phase
      count = 0
      Disable Phase
      count = 0
      count = 0
      count = 0
      count = 0
      Counter Starts, count 4 times
      count = 1
      count = 2
      count = 3
      count = 4
      Counter Stops, 4 times
      count = 4
      count = 4
      count = 4
      count = 4
      Counter continues until it wraps over
      count = 5
      count = 6
      count = 7
      count = 8
      count = 9
      count = 10
      count = 11
      count = 12
      count = 13
      count = 14
      count = 15
      count = 0
      count = 1
      count = 2
      count = 3
      count = 4
      Kết quả khi định nghĩa TIME

      Reset phase
      at 0 ns; count = 0
      Disable Phase
      at 10 ns; count = 0
      at 20 ns; count = 0
      at 30 ns; count = 0
      at 40 ns; count = 0
      Counter Starts, count 4 times
      at 50 ns; count = 1
      at 60 ns; count = 2
      at 70 ns; count = 3
      at 80 ns; count = 4
      Counter Stops, 4 times
      at 90 ns; count = 4
      at 100 ns; count = 4
      at 110 ns; count = 4
      at 120 ns; count = 4
      Counter continues until it wraps over
      at 130 ns; count = 5
      at 140 ns; count = 6
      at 150 ns; count = 7
      at 160 ns; count = 8
      at 170 ns; count = 9
      at 180 ns; count = 10
      at 190 ns; count = 11
      at 200 ns; count = 12
      at 210 ns; count = 13
      at 220 ns; count = 14
      at 230 ns; count = 15
      at 240 ns; count = 0
      at 250 ns; count = 1
      at 260 ns; count = 2
      at 270 ns; count = 3
      at 280 ns; count = 4
      Cái test bench có 2 mô hình khác nhau tùy theo có định nghĩa của "TIME" hay không. Khi "TIME" được định nghĩa, kết quả in ra sẽ mô tả một thời gian ảo giống như khi simulate khối RTL. Mỗi lần hàm được gọi, bạn cứ hình dung là tiến lên một đon vị của xung clock. Trong trường họp này, xung clock có tần số là 100MHZ.

      Đây là ví dụ để tôi giới thiệu về thời gian trong miền không thời gian (untime domain). Trong những bước kế tiếp, tôi sẽ bắt đầu viết về systemC và sẽ giới thiệu về hoạt động song song (multi-thread).

      Các bạn nếu có cơ hội thì dùng ví dụ trên để làm những ví dụ khác để chia xẻ thêm về đề tài này nhe. Mong được sự đóng góp của các bạn

      Chào
      Tony
      Last edited by tonyvandinh; 12-04-2010, 00:51.
      Chúc một ngày vui vẻ
      Tony
      email : dientu_vip@yahoo.com

      Comment


      • #4
        systemC data type

        Trước khi đi sâu vào cấu trúc của systemC, tôi xin giới thiệu về systemC data type. Như các bạn đã biết native C data type chỉ có thể diễn tả độ rộng nhân 8. Ví dụ "char" cho 8 bits, "short" cho 16 bits, "int" cho 32 bits. Để diễn tả dùng những độ rộng khác đòi hỏi phải thêm chi tiết để điều hành. Trong ví dụ của "counter" trên, tôi phải thử count với 15 để quyết định đếm tiếp hay trở lại 0. Nếu có độ rộng 4 bits cho count thì tôi không phải làm cái thử này và để nó tự nhiên trở lại 0 khi đã đạt mức tối đa. Cho nên bài counter ở trên sẽ được viết lại như sau khi dùng systemC data type.

        Code:
        #include "systemc.h"
        #define CBITS 4
        
        sc_uint<CBITS> counter(bool *reset, bool *enable)
        {
        	static sc_uint<CBITS> count = 0;
        	
        	if (*reset)
        		count = 0;
        	else if (*enable)
        		count++;
        		
        	return count;
        }
        và tiện đây tôi cũng đổi hàm printf qua cout vì dùng cout tiện hơn printf để in ra những data type khác mà không cần phải đổi về data type nguyên thủy (native). Vì vậy bài test bench sẽ viết lại như sau:

        Code:
        #define TIME
        #define PERIOD 10
        
        void my_print(int &count, int &tnow)
        {
        	#ifdef TIME
        	cout << "at " << tnow << " ns; count = " << count << endl;
        	#else
        	cout << "count = " << count << endl;
        	#endif
        }
        
        int main()
        {
        	bool reset, enable;
        	
        	// Reset
        	reset = 1;
        	enable = 0;
        	int count;
        	int tnow = 0;
        	
        	cout << "Reset phase" << endl;
        	count = counter(&reset, &enable);
        	my_print(count, tnow);
        	tnow += PERIOD;
        	
        	// Release reset
        	reset = 0;
        	cout << "Disable Phase" << endl;
        	
        	for (int i=0; i<4; i++)
        	{
        		count = counter(&reset, &enable);
        		my_print(count, tnow);
        		tnow += PERIOD;
        	}
        	
        	// Enable counter
        	enable = 1;
        	cout << "Counter Starts, count 4 times" << endl;
        	
        	for (int i=0; i<4; i++)
        	{
        		count = counter(&reset, &enable);
        		my_print(count, tnow);
        		tnow += PERIOD;
        	}
        
        	// Disable counter
        	enable = 0;
        	cout << "Counter Stops, 4 times" << endl;
        	
        	for (int i=0; i<4; i++)
        	{
        		count = counter(&reset, &enable);
        		my_print(count, tnow);
        		tnow += PERIOD;
        	}
        
        	// Enable counter
        	enable = 1;
        	cout << "Counter continues until it wraps over" << endl;
        	
        	for (int i=0; i<16; i++)
        	{
        		count = counter(&reset, &enable);
        		my_print(count, tnow);
        		tnow += PERIOD;
        	}
        
        	return(0);
        }
        Các bạn có thể theo cái link dưới đây để lấy thêm chi tiết về data type nhe.

        http://en.wikipedia.org/wiki/SystemC#Data_types

        Hẹn các bạn ở bước kế
        Chào
        Tony
        Chúc một ngày vui vẻ
        Tony
        email : dientu_vip@yahoo.com

        Comment


        • #5
          Hm, không thấy ai hỏi hoặc có ý kiến gì cho nên tôi không biết cái tutorial này có ích lợi hay không! Chắc tôi xin tạm ngưng ở đây vậy. Chúc các bạn tự tìm tòi thêm.

          Chào
          Tony
          Chúc một ngày vui vẻ
          Tony
          email : dientu_vip@yahoo.com

          Comment


          • #6
            SC_MODULE và SC_METHOD

            Dưới đây là code tôi viết lại dùng cấu trúc của systemC và hình ảnh của simulation.

            Attached Files
            Last edited by tonyvandinh; 16-04-2010, 00:25.
            Chúc một ngày vui vẻ
            Tony
            email : dientu_vip@yahoo.com

            Comment


            • #7
              Với trigger

              Bài này viết lài để thêm trigger event giống như xung clock.

              Attached Files
              Last edited by tonyvandinh; 16-04-2010, 00:25.
              Chúc một ngày vui vẻ
              Tony
              email : dientu_vip@yahoo.com

              Comment


              • #8
                GTKwave

                Để có thể đọc được VCD (Value Change Dump) file, bạn có thể dùng GTKWave mà tôi đính kèm ở đây. Sau khi down, bạn cần unzip qua c:\ rồi thêm c:\gtkw vô path. Sau đó bạn có thể đăng ký vcd extension cho gtkwave để tiên dụng
                Attached Files
                Chúc một ngày vui vẻ
                Tony
                email : dientu_vip@yahoo.com

                Comment


                • #9
                  cám ơn, dù không dùng nhưng biết qua hoặc làm reference cũng tốt ; và đặc biệt cám ơn tâm huyết của anh

                  Comment


                  • #10
                    Nguyên văn bởi tarzanaly Xem bài viết
                    cám ơn, dù không dùng nhưng biết qua hoặc làm reference cũng tốt ; và đặc biệt cám ơn tâm huyết của anh
                    Có lẽ chưa dùng thì đúng hơn là tại vì systemC là hướng chuyển mới để nâng cấp thiết kế trong tương lai. Nếu có cơ hội để học hỏi và nghiên cứu thì nên vì RTL đã tới mức không còn phát triển cao lên để làm những thiết kế phức tạp trong thời gian hạn chế. Kỹ thuật hiện nay tiến rất nhanh nếu không chuẩn bị sẽ trở tay không kịp. Trình độ thiết kế RTL ở VN chậm hơn Mỹ và Âu Châu hơn 20 năm, với mấy nước Á Châu là 15 năm và đây là cơ hội để bắt theo. Nếu để lỡ cơ hội này thì lâu lắm mới có lại cơ hội khác
                    Chúc một ngày vui vẻ
                    Tony
                    email : dientu_vip@yahoo.com

                    Comment


                    • #11
                      Hôm nay search mới thấy bài này của a Tony.

                      Jeff thử model mạch DFF với clock enable:
                      SC_MODULE(DFF){
                      sc_in<sc_logic> ce;
                      sc_in_clk clk;
                      sc_in<sc_lv<8>> din;
                      sc_out<sc_lv<8>> dout;

                      void execute(void)
                      {
                      if(ce.read()==1)
                      {
                      dout.write(din.read());
                      }
                      }

                      SC_CTOR(DFF)
                      {
                      cout<<"DFF created"<<endl;
                      SC_METHOD(execute);
                      sensitive<<clk.pos();
                      }
                      };
                      Lúc chạy thì waveform nó hơi kì,

                      Khi simulate thì J cho ce=1 và din=0xA cùng 1 lúc (lúc rising_edge của clock), thì thấy dout thay đổi tức thì, cùng clock đó luôn. Cái này khác với VHDL J thường simulate.
                      Quy ước của SystemC trong trường hợp này là như thế nào vậy?

                      Comment


                      • #12
                        Jeff có thể bỏ waveform lên kô? Theo như tôi hiểu là J thắc mắc là tại sao không có thời gian trễ của dout sau clk pos()? Tùy VHDL simulator thì có thể có 1 unit delay sau clock. Còn systemC thì hoàn toàn untime. Nếu J muốn nó hoạt động giống RTL thì vẫn có thể bỏ time vô.
                        Chúc một ngày vui vẻ
                        Tony
                        email : dientu_vip@yahoo.com

                        Comment


                        • #13
                          Ý J là vầy, shift được nối vào CE của FF. VHDL simulator thì sẽ cho dout trễ hơn 1 clock so với din.
                          Attached Files

                          Comment


                          • #14
                            Nguyên văn bởi jefflieu Xem bài viết
                            Ý J là vầy, shift được nối vào CE của FF. VHDL simulator thì sẽ cho dout trễ hơn 1 clock so với din.
                            Jeff cần phải stimulus CE và din ít nhất 1 đơn vị của simulation resolution sau xung clock:

                            Code:
                            #include <systemc.h>
                            
                            #define DELAY 0.1
                            SC_MODULE(DFF){
                              sc_in<sc_logic> ce;
                              sc_in_clk clk;
                              sc_in<sc_lv<8> > din;
                              sc_out<sc_lv<8> > dout;
                            
                              void execute(void)
                              {
                                if(ce.read()==1)
                                {
                                  dout.write(din.read());
                                }
                              }
                              
                              SC_CTOR(DFF) :
                                clk("clk"), ce("ce"), din("din"), dout("dout")
                              {
                                cout<<"DFF created"<<endl;
                                SC_METHOD(execute);
                                sensitive<<clk.pos();
                              }
                            };
                            
                            SC_MODULE(tb)
                            {
                              sc_out<sc_logic> ce;
                              sc_out<sc_lv<8> > din;
                              sc_in<sc_lv<8> > dout;
                              
                              void stim()
                              {
                                wait(DELAY, SC_NS);
                                
                                ce = sc_logic(0);
                                din = sc_lv<8> (0);
                                
                                wait(100, SC_NS);
                                ce = sc_logic(1);
                                
                                for (int i=0; i<10; i++)
                                {
                                  din = sc_lv<8> (rand() % 256);
                                  wait(10, SC_NS);
                                }
                                sc_stop();
                              }
                              
                              SC_CTOR(tb)
                              {
                                SC_THREAD(stim);
                              }
                            };
                            
                            int sc_main(int argc, char *argv[])
                            {
                              DFF dut("dut");
                              tb stim("stim");
                              
                              sc_signal<sc_logic> ce;
                              sc_clock clk("clk", 10, SC_NS);
                              sc_signal<sc_lv<8> > din;
                              sc_signal<sc_lv<8> > dout;
                              
                              dut(ce, clk, din, dout);
                              stim(ce, din, dout);
                                
                              sc_start(-1);
                              return 0;
                            }
                            Attached Files
                            Last edited by tonyvandinh; 04-05-2010, 01:35.
                            Chúc một ngày vui vẻ
                            Tony
                            email : dientu_vip@yahoo.com

                            Comment


                            • #15
                              Hm, thanks a de J suy nghĩ

                              Comment

                              Về tác giả

                              Collapse

                              tonyvandinh A high tech engineer Tìm hiểu thêm về tonyvandinh

                              Bài viết mới nhất

                              Collapse

                              Đang tải...
                              X