'Prototype'에 해당되는 글 2건

  1. 2012.02.06 하드웨어 설계에도 TDD를 (4) - Ruby-VPI (2)
  2. 2009.03.26 "그분" 전용의 SilverChip
ASIC SoC2012. 2. 6. 19:20

Ruby-vpi를 테스트 하는 과정을 정리하였다.
여기서 사용하는 예제는 아래 링크에서 참조 하였다.

http://snk.tuxfamily.org/lib/ruby-vpi/#usage.tutorial.declare-design

디자인은 counter.v 이다.

일단 Top module부터 만든다.

module counter #(parameter Size = 5) (
  input                   clock,
  input                   reset,
  output reg [Size-1 : 0] count
);
endmodule


일단 폴더를 만들고

mkdir xUnit

디자인을 옮겨 둔다.
cp counter.v ./xUnit

그리고 해당 폴더로 가서 xUnit용 파일을 만든다.


GUNDAM-NT:xUnit kevinim$ ruby-vpi generate counter.v --xUnit

  module  counter
  create  counter_runner.rake
  create  counter_design.rb
  create  counter_proto.rb
  create  counter_spec.rb
  create  counter_loader.rb
  create  Rakefile 


위와 같이 커맨드를 넣으면 그에 맞게 파일이 만들어진다.
각각 앞에서 설명하였던 *.rake *_design.rb _proto.rb *_spec.rb *_loader.rb Rakefile 등이다.

(2) Spec 생성

카운터라는 것의 특성상 기본적인 내용은 아래와 같이 정의할 수 있겠다.
- 초기 값은 0이어야 한다.
- 상승 클럭에서 카운트 값이 1씩 증가한다.
- 최대 값에 도달하면 overflow가 발생하지만 하여튼 0부터 시작한다.

이것을 스펙으로 정의하면 아래와 같다.

require 'test/unit'

# lowest upper bound of counter's value
LIMIT = 2 ** DUT.Size.intVal

# maximum allowed value for a counter
MAX = LIMIT - 1


class A_counter_when_reset < Test::Unit::TestCase
  def setup
    DUT.reset! # reset the counter
  end

  def test_should_be_zero
    assert_equal( 0, DUT.count.intVal )
  end

  def test_should_increment_upon_each_subsequent_posedge
    LIMIT.times do |i|
      assert_equal( i, DUT.count.intVal )
      DUT.cycle! # increment the counter
    end
  end
end

class A_counter_with_the_maximum_value < Test::Unit::TestCase
  def setup
    DUT.reset! # reset the counter

    # increment the counter to maximum value
    MAX.times { DUT.cycle! }
    assert_equal( MAX, DUT.count.intVal )
  end

  def test_should_overflow_upon_increment
    DUT.cycle! # increment the counter
    assert_equal( 0, DUT.count.intVal )
  end
end

 크게 2개의 클래스를 만들었는데
하나가  A_counter_after_being_reset 이고
나머지 하나가 A_conter_with_the_maximum_value 이다.

각각 다음과 같은 동작을 수행한다.
 
 
A_counter_after_being_reset 
-  setup :: Reset을 건다. 
- test_should_be_zero :: 0인지 확인한다. 
- test_should_increment_upon_each_subsequent_posedge :: 계속 증가하면서 하나씩 커지는 것을 확인한다. 

A_counter_with_the_maximum_value
- setup :: 리셋을 건다.
- test_should_overflow_upon_increment :: overflow가 되면 0이 된다.

이다.

(3) Prototype을 만든다.

counter_proto.rb 파일에서 만든다.

if RubyVPI::USE_PROTOTYPE
  always do
    wait until DUT.clock.posedge?

    if DUT.reset.t ?
      DUT.count.intVal = 0 
    else
      DUT.count.intVal  += 1
   end
  end
end
      
 
카운터의 값의 프로토 타입을 의미한다.


(4) Prototype을 검증하기

검증은 다음과 같이 한다.

GUNDAM-NT:xUnit kevinim$ rake ivl PROTOTYPE=1 
(in /Users/kevinim/Documents/Verilog_toos/ruby-vpi-test/xUnit)
rake aborted!
no such file to load -- ruby-vpi/runner_proxy

옵션으로 ivl은 icarus verilog simulator를 의미한다.

위와 같은 오류가 발생한다.
 
ruby-vpi/runner_proxy 

를 찾을 수 없다는 오류이다.

이 파일은 라이브러리에 있으므로 환경 변수를 설정한다.

export RUBYLIB=/Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ 

이후에 다시 실행한다.

GUNDAM-NT:xUnit kevinim$ rake ivl PROTOTYPE=1 
(in /Users/kevinim/Documents/Verilog_toos/ruby-vpi-test/xUnit)
rake -f counter_runner.rake ivl PROTOTYPE=1
(in /Users/kevinim/Documents/Verilog_toos/ruby-vpi-test/xUnit)
cp /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/obj/ivl.so ruby-vpi.vpi
["iverilog", "-mruby-vpi", "counter.v", {:verbose=>:default, :noop=>false}]
iverilog -mruby-vpi counter.v
["vvp -M. a.out", {:verbose=>:default, :noop=>false}]
vvp -M. a.out
ruby-vpi: prototype is enabled
SyntaxError: compile error
counter_proto.rb:6: syntax error, unexpected '\n'
counter_proto.rb:12: syntax error, unexpected kEND, expecting $end
        from counter_proto.rb:12:in `load_test'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi.rb:68:in `each'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi.rb:68:in `load_test'
        from ./counter_loader.rb:1
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/boot/loader.rb:146
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/scheduler.rb:121:in `call'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/scheduler.rb:121:in `initialize'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/generator.rb:83:in `call'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/generator.rb:83:in `initialize'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/scheduler.rb:119:in `new'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/scheduler.rb:119:in `initialize'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/scheduler.rb:53:in `new'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/scheduler.rb:53:in `run'
        from /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/boot/loader.rb:144


몇개의 오류가 보인다.
이것을 먼저 수정하고 진행한다.

GUNDAM-NT:xUnit kevinim$ vi counter_proto.rb 
GUNDAM-NT:xUnit kevinim$ rake ivl PROTOTYPE=1 
(in /Users/kevinim/Documents/Verilog_toos/ruby-vpi-test/xUnit)
rake -f counter_runner.rake ivl PROTOTYPE=1
(in /Users/kevinim/Documents/Verilog_toos/ruby-vpi-test/xUnit)
cp /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/obj/ivl.so ruby-vpi.vpi
["iverilog", "-mruby-vpi", "counter.v", {:verbose=>:default, :noop=>false}]
iverilog -mruby-vpi counter.v
["vvp -M. a.out", {:verbose=>:default, :noop=>false}]
vvp -M. a.out
ruby-vpi: prototype is enabled
Loaded suite ruby-vpi
Started
EEE
Finished in 0.00128 seconds.

  1) Error:
test_should_be_zero(#<Module:0x10252d340>::A_counter_when_reset):
ArgumentError: "VpiHigh" is not a valid VPI property
    /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/handle.rb:364:in `initialize'
    /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/handle.rb:288:in `new'
    /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/handle.rb:288
....
  2) Error:
test_should_increment_upon_each_subsequent_posedge(#<Module:0x10252d340>::A_counter_when_reset):
ArgumentError: "VpiHigh" is not a valid VPI property
    /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/handle.rb:364:in `initialize'
    /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/handle.rb:288:in `new'
 ....

  3) Error:
test_should_overflow_upon_increment(#<Module:0x10252d340>::A_counter_with_the_maximum_value):
ArgumentError: "VpiHigh" is not a valid VPI property
    /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/handle.rb:364:in `initialize'
    /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/handle.rb:288:in `new'
    /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/lib/ruby-vpi/core/handle.rb:288
...

3 tests, 0 assertions, 0 failures, 3 errors
     
위의 에러는 뜻밖인데,
Ruby-VPI에서 버그가 있는것이다.
Test Code용으로 만들어낸 디자인에서 code가 틀리게 되어 있다.

counter_design.rb 를 아래와 같이 수정한다.


# Simulates the design under test for one clock cycle.
def DUT.cycle!
  clock.t!
  advance_time

  clock.f!
  advance_time
end

# Brings the design under test into a blank state.
def DUT.reset!
  reset.t!
  cycle!
  reset.f!
end
 
그리고 시뮬레이션을 수행하면 다음과 같은 오류가 발생한다.

GUNDAM-NT:xUnit kevinim$ rake ivl PROTOTYPE=1
(in /Users/kevinim/Documents/Verilog_toos/ruby-vpi-test/xUnit)
rake -f counter_runner.rake ivl PROTOTYPE=1
(in /Users/kevinim/Documents/Verilog_toos/ruby-vpi-test/xUnit)
cp /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/obj/ivl.so ruby-vpi.vpi
["iverilog", "-mruby-vpi", "counter.v", {:verbose=>:default, :noop=>false}]
iverilog -mruby-vpi counter.v
["vvp -M. a.out", {:verbose=>:default, :noop=>false}]
vvp -M. a.out
ruby-vpi: prototype is enabled
 MAX   is 31
 SIZE  is 5
 Limit is 32
Loaded suite ruby-vpi
Started
.FF
Finished in 0.059358 seconds.

  1) Failure:
test_should_increment_upon_each_subsequent_posedge(#<Module:0x10232d3d8>::A_counter_when_reset)
    [counter_spec.rb:27:in `test_should_increment_upon_each_subsequent_posedge'
     counter_spec.rb:26:in `times'
     counter_spec.rb:26:in `test_should_increment_upon_each_subsequent_posedge']:
<1> expected but was
<0>.

  2) Failure:
test_should_overflow_upon_increment(#<Module:0x10232d3d8>::A_counter_with_the_maximum_value) [counter_spec.rb:39]:
<31> expected but was
<0>.

3 tests, 4 assertions, 2 failures, 0 errors
 
이번의 오류는 RUBY와 icaurs가 연결이 되지 않는다는 의미이다.

그래서 이번에는 CVER로 바꾸어서 컴파일을 해본다.
GPLCver에 대한 설치는 이 페이지를 참조하고 여기서는 그냥 진행한다

GUNDAM-NT:xUnit kevinim$ rake cver PROTOTYPE=1
(in /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/examples/counter/xUnit)
rake -f counter_runner.rake cver PROTOTYPE=1
(in /Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/examples/counter/xUnit)
["cver", "+loadvpi=/Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/obj/cver.so:vlog_startup_routines_bootstrap", "+incdir+..", "../counter.v", {:verbose=>:default, :noop=>false}]
cver +loadvpi=/Users/kevinim/Documents/Verilog_toos/Ruby-VPI/ruby-vpi-21.1.0/obj/cver.so:vlog_startup_routines_bootstrap +incdir+.. ../counter.v
GPLCVER_2.12a of 05/16/07 (Mac OSX).
Copyright (c) 1991-2007 Pragmatic C Software Corp.
  All Rights reserved.  Licensed under the GNU General Public License (GPL).
  See the 'COPYING' file for details.  NO WARRANTY provided.
Today is Wed Nov  2 19:37:38 2011.
Compiling source file "../counter.v"
Highest level modules:
counter

ruby-vpi: prototype is enabled
Loaded suite ruby-vpi
Started
...
Finished in 0.103285 seconds.

3 tests, 35 assertions, 0 failures, 0 errors
0 simulation events and 0 declarative immediate assigns processed.
1 behavioral statements executed (1 procedural suspends).
  Times (in sec.):  Translate 0.0, load/optimize 0.1, simulation 0.3.
  There were 3 error(s), 136 warning(s), and 4 inform(s).
End of GPLCVER_2.12a at Wed Nov  2 19:37:38 2011 (elapsed 0.3 seconds).

결과는 이상없이 잘 진행된다.
아마도 icarus와 ruby-vpi가 잘 안맞는 문제인듯..
Osx에서만 안맞는것인지 linux에서도 그런지는 확인을 하지 못하였다.
 
 
이 방법은 불안정 해서  더이상 진행하지 않습니다.
나중에 Linux + ModelSim이나 VCS로 테스트 해보고 되면 진행 예정입니다.


 
Posted by GUNDAM_IM
ASIC SoC2009. 3. 26. 07:49

이번에 칩을 하나 만들면서 SilverChip 기능을 넣었습니다.


ARM926-EJS로 여러가지 기능을 많이 넣어서 만들었습니다만,


그중에 백미는

 Graphic Accelerator 와

 SilverChip기능입니다.


Silver Chip이란 프로세서 Core와 그 Core의 AHB버스가 밖으로 나와서 동작하는 Chip입니다.

내부에서는 ARM926 Core와 약간의 Glue Logic이 들어간 것입니다.

ARM사에서 제공하는 CoreTile B/D의 칩을 생각하시면 맞습니다.


이번에 개발한 칩은 본래 목적은 그래픽/미디어 처리 프로세서이지만

그 외에도 내부 개발용으로 사용하기 위해서 Silver Chip 기능을 추가해서 만든 것입니다.


보드를 만들때,  "그분" 전용으로 만들려고 붉은색으로 PCB를 만들었습니다.

패키지도 "그분" 전용 답게 붉은색으로 하면 좋지만, 검정색 밖에 없어서 아쉽습니다.

물론 통상 3배의 속도로 동작하지는 않습니다. (^^)


멋질거라 생각했고 나온 보드 색상도 나름 괜찮은데,


보드 색상에 대해서 결과물을 보고 멤버들이 비난아닌 비난을 조금 해서..

맘 상했습니다. 쩝..

아직도 건담의 로망을 모르다니..


AHB에 대한 테스트와 , SoC Chip의 프로토 타입 FPGA 검증 등, 보드 개발시에 편리성 등을 따져보면,

통상 3배의 (속도가 아니고) 개발 편의성을 자랑할 수 있습니다.ㅋㅋ


아래에 사진을 올립니다


사용자 삽입 이미지

밑에 있는 보드는 자체 개발한 프로토 타입 보드입니다.

그동안 프로토타입 보드를 3개를 개발했는데 그중 3번째보드입니다.

Virtex 5 제일 큰것이 2개 들어간 막강 보드입니다.


사용자 삽입 이미지

이것이 마지막 프로토타입보드가 되었으면 하는데 Virtex6가 가을에 나오고

용량이 Virtex5의 2배가 된다고 하니


나중에는 그분 전용 프로토 타입보드를 개발해야 하지 않을까 합니다.


아니면 그때는 GOLD로 해볼까요 ? KOG를 고려해 봐야하지 않을까 생각합니다.

그럼 파티마도  필요할텐데~

Posted by GUNDAM_IM