ASIC SoC2010. 12. 23. 10:42
Module hierarchy and file organization

Distribution code organization

RTL 코드의 계층 구조는 아래와 같습니다.
사용자 삽입 이미지
기본 계층 구조는 ORPSOC에서 시작합니다. 테스트를 위한 패스는 ORPSOC_FPGA_TOP을 기준으로 시작합니다.
각각의 IP를 연결하는 BUS Connection은 tcop_top이고 나머지는 이름을 기준으로 유추하여 볼 수 있습니다.

testbench의 코드를 보면 탑레벨 module의 이름은  orpsoc 입니다.
그리고 앞서 설명한 l.nop명령어들의 동작을 반영하는 것이 or1200_monitor 모듈입니다.

Verilator model에서는 이러한 기능은 SystemC 모델로 제공됩니다.

이 강의에서 사용되는 모든 파일은 tar  파일로 제공됩니다만,
필요하면 opencore.org 에서 새로 받아서 사용할 수 있습니다. 이 경우에는 필요한 몇개 파일을 수정해야
합니다.

tar 파일은 아래 링크에서 다운 받을 수 있습니다.

http://www.embecosm.com/download/esp5.html

Distribution code organization


tar 파일을 풀면 몇개의 폴더가 보이게 됩니다.
그 구조는 아래와 같습니다.

Top level directory
    - Makefile
        main 프로젝트 파일입니다. verilator를 이용해서 프로젝트를 빌드 할 수 있도록 해 줍니다.
    - Testbench file
        orpsocmain.cpp , orpsocmain.h
        verilator를 위한 테스트 벤치 파일입니다.
        자세한 설명은 다음에 하기로 하고
        여기서는 그냥 이런 파일들이 Top Folder에 있다는 것만 알고 있으면됩니다.

orp_soc
     현재 ORPSoC 버전이 들어가 있습니다.
     이것은 www.opencores.org에서 구할 수 있는것과 같습니다.

local
     orp_soc의 shadow 폴더입니다. local로 수정할 파일을 이곳에 두게 됩니다.
     그리고 PATH변수에 의해서 Search 순서를 지정하여 두었기 때문에 이곳에서 바꾸게 됩니다.

sim
    icarus 시뮬레이터용 스크립트가 들어 있는 폴더입니다.
    *.scr  파일이 이 폴더 입니다.

sysc_modules
    systemc로 작성된 모듈들이 있으며, 이 모듈들은 테스트 벤치를 구성하는 일부 입니다.
    or1200monitorSC와  ResetSC가 들어 있습니다.

verilator-model
    이 폴더에는  verilator에서 사용하는 커맨드 파일과
    verilator model 내부의 시그널을 볼 수 있는 OrpsocAccess  가 있습니다.
    

Original ORPSoC Source code organization


  원래의 orpsoc의 소스 트리 구조는 orp_soc 폴더에서 찾아 볼 수 있습니다.
 
bench
   테스트 벤치 코드입니다.
   서브 디렉토리로 verilog를 가지고 있고 (사실 이것밖에 없습니다.) 이 폴더 내에 ORPSoC를 위한
    Verilog Code를 가지고 있습니다.  
    일단 두개의 헤더 파일을 찾아 볼 수 있습니다.
    bench_defines.v
      `define 들이 들어 있습니다.
    timescale.v
      `timescale에 대한 정의가 있습니다.

doc
   당연히 문서가 모여 있습니다.

rtl
   ORPSoC의 verilog code가 있습니다.

sw
   타겟 소프트웨어 입니다.
   이 코드들은 컴파일 되어서 내부의 Flash memory에 올려져서 운용됩니다.
   utils  폴더에 있는 파일들을 먼저 빌드해야 합니다.
   이 후에 support 파일을 빌드합니다.
   나머진 필요할 때 순서에 상관 없이 빌드하면 됩니다.


Modifications to the ORPSoC source code


local 폴더에는 앞서 설명하대로
원래의 코드를 수정하지 않고 이쪽에서 수정할 수 있도록 해주는 파일을 모아두었습니다.
그리고 PATH 순서를 바꾸어서 이쪽 파일들이 먼저  선택되도록 하였습니다.

(1) bench/verilog/bench_defines.v.
        half clock을 50nS로 정의해서 전체 동작을 10MHz로 되도록 만들어 두었습니다.

원래는 아래와 같이 되어 있지만 local  폴더에서 수정되어 있습니다.
........
//
// OR1200 clock mode
//
`ifdef OR1200_CLMODE_1TO2
`define CLK2_HALFPERIOD 25
`else
`ifdef OR1200_CLMODE_1TO4
Unsuppported
`else                  
`define CLK2_HALFPERIOD 50
`endif
`endif
..........

local 폴더의 bench_defines.v 파일은 아래와 같습니다.

.....
//
// Clock half period for simulation (10MHz)
//
`define BENCH_CLK_HALFPERIOD 50
....



(2) bench/verilog/or1200_monitor.v
   여러차례 설명한 l.nop xxxx 명령어로 내부 정보를 얻어내는 기능을 넣어둔 파일입니다.
   내부에 코드를 보면 쉽게 알 수 있습니다.

(3) bench/verilog/orpsoc_bench.v
    원래의 코드는 bench/verilog/xess_top.v 입니다.
   이 파일은 xilinx용 top 파일입니다.
   이 코드를 wrapping 하여서 ORPSOC용으로 테스트 벤치를 구성한 것이 이 파일 입니다.

(4) rtl/verilog/orpsoc_fpga_top.v
    Top 레벨의 FPGA 모델입니다.
    ORPSoC의 FPGA Top 파일이됩니다.

(5) rtl/verilog/orpsoc_fpga_defines.v
     rtl/verilog/xsv_fpga_defines.v를 다시 정의한 것입니다.
      주요한 내용은 주로
      `define TARGET_VIRTEX
    을 제거하여서 자이링스용 라이브러리를 사용하지 않도록 막아둔 것입니다.

(6) rtl/verilog/or1200_defines.v
    현재 사용하는 형태로 적합하도록 프로세서의 내용을 다시 설정하였습니다.
    주로 캐쉬나 MMU의 사용 여부를 설정하는데 사용합니다.
    그리고 나눗셈기등의 사용 여부를 결정합니다.

(7) rtl/verilog/ssvga/ssvga_fifo.v
         rtl/verilog/ssvga/ssvga_top.v
         rtl/verilog/ssvga/ssvga_dpram_4x8x16.v
         rtl/verilog/ssvga/ssvga_dpram_4x16x16.v
 
     ORPSoC 내에서 사용되는 메모리 블럭등에 대한 정의를 합니다.

Posted by GUNDAM_IM
ASIC SoC2010. 12. 2. 15:37

The Example Design



 

Memory Map

 
사용자 삽입 이미지

 메모리 맵은 위와 같습니니다.
 Instruction Memory (ROM)은 0x0400_0000에 위치합니다.
 부팅시에 부팅 코드를 SRAM으로 카피하고 움직이게 됩니다.

 Interrupt Assignments

 
 OpenRISC 1000은 프로그래머블한 인터럽트 코아를 가지고 있고, 외부에서 20개의 인터럽트를 연결할 수 있습니다. 그중에서 사용하는 인터럽트는 아래와 같이 배치되어 있습니다.

사용자 삽입 이미지

Test Bench Modeling of Peripherals


Peripherals들은 모델링이 되어 있지 않습니다
외부 포트들은 모두 적당한 값으로 매핑되어 둡니다.

ORPSoC의 트래킹은 OpenRISC 100의 l.nop 명령어를 활용하여서 내부 정보를 얻어냅니다.
l.nop 명령은 immediate 값을 가질 수 있는데 이 값에 적당한 값을 할당 함으로서 원하는 동작을 수행합니다.

여기서 사용하는 방식은 아래 테이블에 정리되어 있다.

사용자 삽입 이미지
 다른 l.nop의 인자는 모두 무시합니다.
 testbench 구현은 이 새로운 l.nop 명령을 활용하여 구현하게 됩니다.
 

Test Software Application


Test Application은 Dhrystone 2.1 벤치마크 프로그램을 활용합니다.
앞서 설명한 n.lop 명령을 활용하여 라이브러리 중 일부룰 수정하여서 필요한 정보를 프린트하거나 얻게 됩니다.

OpenRISC 1000의 l.nop 명령어 사용하기

앞서 설명했듯이 l.nop명령은 16비트의 immediate 값을 가지고 움직입니다.
이 값은 CPU에서는 무시되지만, 테스트 벤치에 의해서 모니터링 되고 사용됩니다.
이 ORPSoC에서는 이것을 이용해서 I/O를 제공하고, C Code가 운용될 때 내부 정보를 얻을 수 있는 컨트롤 함수의 기능을 구현하는 활용합니다.

l.nop 1  : 32'h1500_0001
    GPR3에 있는 값을 리턴코드로 하여 프로그램을 끝냅니다.
    C Lib 함수는 다음과 같이 구현됩니다.

void exit (int i)
{
  asm("l.add r3,r0,%0": : "r" (i));
  asm("l.nop %0": :"K" (NOP_EXIT));
  while (1);
}



l.nop 2  : 32'h1500_0002
    GPR 3의 값을  Hex로 덤프하여 줍니다.

l.nop 3  : 32'h1500_0003
    printf을 지원해 주지만 아직까지는 제대로 구현이 안되어 있다.

l.nop 4  : 32'h1500_0004
    LSB를 Character로 프린트 해줍니다.
    PUTC를 구현하는 것은 아래와 같습니다.

void putc(int value)
{
  asm("l.addi\tr3,%0,0": :"r" (value));
  asm("l.nop %0": :"K" (NOP_PUTC));
}
	  
   이것을 이용해서 나중에 printf등을 구현할 수 있을 겁니다.




Posted by GUNDAM_IM
ASIC SoC2010. 12. 2. 15:37

High Performance SoC Modeling with Verilator


이번에 정리하는 것은 Verilator를 이용해서 OpenRISC 프로세서를 시뮬레이션하는 것입니다. 기본적인 플로우는 ICARUS라는 GNU Verilog 시뮬레이터 환경을 바꾸어서 진행하는 것입니다.

관련한 원본 자료는 아래 페이지에 있습니다.

http://www.embecosm.com/download/ean6.html

진행하는 플랫폼은 MAC이지만, Verildator는 Platform Independent하므로 대부분의 플랫폼에서 작동할 것으로 생각됩니다.

플랫폼별 차이점이 있다면, 나중에 기회가 되면 정리하겠습니다.
- 즉 귀찮아서 하지 않을 수도 있다는 의미입니다.

전제 사항들...


(1) Verilator를 설치하고 테스트 하는 방법은 앞서 정리한 블로그 자료를 참조하시기 바랍니다.
     역시 플랫폼 독립적이므로, 다른 플랫폼에서도 거의 비슷하게 동작할 것입니다.
    
(2) Linux 혹은 MAC의 터미널 환경에 대해서 잘 알고 있다는 가정하에서 설명이 진행됩니다.


다른 책에도 맨날 나오는 내용이지만,  S/W와 하드웨어의 파티셔닝과 그에 다른 시스템의 성능 평가가 중요한 부분인지에 대한 설명입니다.


시스템의 성능에 대해서 정밀한 분석은 하드웨어와 그 하드웨어에 의해서 움직일 임베디드 소프트웨어에 기반합니다.

로레벨의 BSP나 디바이스 드라이버 같은  Embedded Firmware의 구현은 SoC Peripheral의 정확한 동작에 기반하여 구현됩니다.

소프트웨어의 최적화. 이것은 Codec  개발에서 특히 중요한 부분입니다.  특히 이 것은 프로세서와 메모리 캐쉬 MMU등의 상호간 동작에  아주 깊은 영향을 받습니다. 따라서 ISS와 TLM은  잘못된 결과를 도출하는 것을 방지하여 줍니다.


Modeling Language


   Verilator는 Verilog를 C/C++로 변환하여서 컴파일하게 됩니다.
  당연히 C++ 컴파일러의 최적화 효율에 영향을 받게 됩니다.
  그리고 64비트 시스템 환경에서 더 빨리 운용이 됩니다.

OpenRISC는

  www.opencores.org에서 여러명이 설계한 프로세서 입니다.
  명령어 체계상에서는 32비트 외에도 64비트나 DSP등도 있습니다.
  최근에는 좀더 performance를 올린 프로세서를 만드는 프로젝트도 시작하고 있습니다.
  국내외에서 알게 모르게 여러 IP내부 프로세서나 SoC 프로세서로 사용하고 있습니다.

  OpenRSIC 1000은 Verilog로 만들어진 프로세서를 의미하고
  OpenRISC 1200은 OpenRISC Core + SoC Platform을 의미합니다. 완전한 SoC 플랫폼이며, 줄여서 ORPSoC라고 합니다.  

   OpenRISC 1000은 Processor외에도 CACHE나 MMU등을 가지고 있습니다.
  관심을 가질만한 부분은 l.nop라고 하는 nop 명령어입니다. 이 명령어는 하위에 immediate field를 가지고 있는데 이 field를 이용해서 몇가지 옵션을 주고 운용하는 기능을 부여할 수 있습니다. 일종의 MIPS의 Instruction Extension 기능인 UDP 기능을 생각하시면 됩니다.
  여기서는 Simulation시에 몇가지 특수 용도로 사용하지만,  실제 하드웨어에는 영향을 주지 않습니다.
 

The OpenRISC Reference Platform System-on-Chip (ORPSoC)



사용자 삽입 이미지

OPRSo의 전체 구조는 위와 같습니다.
전체 크기는 15만 게이트에 메모리 별도입니다.
이 회로는 Xilinx나 Altera의 FPGA 보드에서 잘 동작합니다.

OPRSoC에는 Flash Memory가 2MB 붙어 있고, 2MB의 SRAM이 연결되어 있습니다.
그외의 메모리는 FlipFlop 스타일 (SRAM스타일) 의 I/F를 가지고 있습니다.

   

 




Posted by GUNDAM_IM