まごころせいじつ堂

浜町庄金 研究開発  マイコンで遊んでばっかりで

2013年02月

CADR 回路図 SPC MEMORY AND POINTER

CADRマシンの回路図を見ていきます。簡単そうな所から。
http://www.unlambda.com/download/cadr/CADR4_schematic.pdf

49ページは18bit+パリティ、32個のメモリでスタック(SPC)を構成。-WCLKに同期。
SPC POINTERは同期式アップダウンカウンタ 74S159を2個。CLK4Fに同期。
SPC POINTERはパワーオンでは不定だが、ポインタの出力SPCPTR4〜SPCPTR0は読めるのでソフトで初期化しろということだろう。スタックのオーバーフロー/アンダーフローはチェックしないので、ソフトの責任で使用しろと書いてある。

 ところで、TTLのみで96ページもある回路図を読むのはなかなかつらいので、信号の生成元とそれを使っている箇所についてのクロスリファレンスが必要かな。気合が足らんと言われそうだが。

cadr 
  

CADRソース調査 メモリについて

CADRマシンの回路図をたよりに中で使われているメモリについて調べた。
Retrocomputing - MIT CADR Lisp Machines

@natsutanさんのブロック図を参照してください。
制御パス 
データパス

以下はPROMだけど組み合わせ回路で実現:
part_32x32prom_maskright i_MSKR A[4:0] D[31:0] 
part_32x32prom_maskleft i_MSKL A[4:0] D[31:0]
part_32x8prom i_DMASK A[4:0] D[7:0]
part_512x49prom i_PROM0 A[8:0] D[48:0] 

このうち512ワードのi_PROM0はデータbit46が欠けている。元々のPROMには[48:47,45:0]の48bitが割り付けられている。74S472×12個。

以下はRAM、caddr.vでのソースではメモリ上のパリティはすでに取り除いてある:
part_32x19ram i_SPC A[4:0] D[18:0] SPC STACK
元は32x2bit 82S21 ラッチ×10個(パリティ付き)

part_32x32ram i_MMEM A[4:0] D[31:0] B-MEMORY(M-MEMORY)
元は32x2bit 82S21 ラッチ×17個(パリティ付き) 

part_2kx5ram i_VMEM0 A[10:0] D[4:0] VMAP STAGE0
元はRAM 1k×1bit 93425A×12個

part_1kx24ram i_VMEM1_2 A[9:0] D[23:0] VMAP STAGE1,2
元はRAM 1k×1bit 93425A×25個

part_1kx32ram i_PDL、i_AMEM A[9:0] D[31:0] PDL MEMORY、A-MEMORY
元はRAM 1k×1bit 93425A×33個(パリティ付き)が2セット

part_2kx17ram i_DRAM A[10:0] D[16:0] DISPATCH MEMORY
元はRAM 1k×1bit 93425A×36個

part_16x49ram i_IRAM A[13:0] D[48:0] INSTRUCTION MEMORY
元はRAM 4k×1bit IN2147×196個

部品としてのRAMは3種類。うちラッチと書いたものはパススルーができる?
INSTRUCTION MEMORYがいちばん大きい。次いでDISPATCH MEMORYで、このあたりを外に追い出せばいけるか。VMAP関連についてはSTAGE0,1,2とcaddr.vソースとの対応付けが今のところはっきりしない。(CADRマシンの前身、CONSマシンのブロック図を参照しているのでその違いかもしれない)

SPC STACK、B-MEMORYのみ中身があるものにしてDE0(CycloneIII EP3C16F484C6)ターゲットで合成してみたら約1時間で4,229/15,408LE (27%)だった。まだ行けそうね。

QuartusIIでCADRのソースをコンパイル 2

QuartusIIでCADRのソースをコンパイル 続き
i_DRAMの中身をカラ(reg 宣言を削りassign DO=DI; とする)にして再度コンパイルしてみた今回は5時間を越えてどんどん進むが停まる気配がない。10時間で打ち切り、すべてのRAMについて同様に中身をカラにしてみた。どうもreg宣言ばかりで明にRAMに割り当てていないようで、これがLE数を消費する原因と思われた。
結果は以下のとおり。
Flow Status Successful - Fri Feb 22 01:17:37 2013
Quartus II 64-Bit Version 12.1 Build 177 11/07/2012 SJ Web Edition
Revision Name caddr
Top-level Entity Name caddr
Family Cyclone IV GX
Device EP4CGX150DF31I7AD
Timing Models Final
Total logic elements 2,929 / 149,760 ( 2 % )
Total combinational functions 2,860 / 149,760 ( 2 % )
Dedicated logic registers 471 / 149,760 ( < 1 % )
Total registers 471
Total pins 27 / 508 ( 5 % )
Total virtual pins 0
Total memory bits 0 / 6,635,520 ( 0 % )
Embedded Multiplier 9-bit elements 0 / 720 ( 0 % )
Total GXB Receiver Channel PCS 0 / 8 ( 0 % )
Total GXB Receiver Channel PMA 0 / 8 ( 0 % )
Total GXB Transmitter Channel PCS 0 / 8 ( 0 % )
Total GXB Transmitter Channel PMA 0 / 8 ( 0 % )
Total PLLs 0 / 8 ( 0 % )
  2929LEですと?ちょっと少なすぎるみたいだけどもここからRAMを盛っていく。
i_DRAM については外付けのDRAMと勘違いしていたのだがDispatchRAMで17bit幅☓11bitアドレスのStaticRAMだった。主記憶はCADRマシンの外にある。caddrではすでにパリティ用の1bitについては削減してあった。
 あとはクロック周り。osc50mhzを外部からの入力として、以下の接続。
osc50mhz-->○--osc0-->○--hifreq1,hifreq2-->○--hfdlyd-->○--hftomm(未使用)
hifreq1,hifreq2は実質同じ、hfdlydはさらに位相の遅れたクロックのつもり。
これらを元にディレイラインで30ns,70nsの遅れを作りRAMのサイクル用などに使っている。
また、NAND2個のたすきがけで制御を行なっている場所が5箇所あり、図面のCLOCK DISTRIBUSIONとMASTER CLOCKはPLLを使用したクロック制御モジュールとして起こしてやらなければならないだろう。これに合わせて非同期SRAM部分も合わせるか。

QuartusIIでCADRのソースをコンパイル

LISPマシンCADRの回路図とVerilog-HDLに変換されたソースリストを見て、これ今のFPGAに収まりそうじゃないかなと思って試しにコンパイルしてみた。もともとはすべてTTLで構成されていて、それをそのままVerilogの記述に変換したものと、きちんと書きなおされたものがある。後者はCADDR Reviced CADR Verilogとして公開されているのでこちらを使った。
Retrocomputing - MIT CADR Lisp Machines
 すでに@natsutanさんが三年前に試されているけど、最近のはどうかな?
[Lisp][Verilog][FPGA]cadrのVerilogソースのコンパイル その1

環境:Windows7 PRIMERGY TX100S1(Core2Quad 2.67GHzに差し替えたもの)
QuartusII 12.1 Build 177 64-bit

新規プロジェクトを作成し、ターゲットデバイスを一番LE数の大きそうなものにする。今回はCycloneIV GXにした。制約条件などのオプション指定はなにもなし。コンパイルにかかった時間は4時間23分、結果はFittingに失敗(113%)、LE数は169,005と出た。

Flow Status Flow Failed - Wed Feb 20 18:15:59 2013
Quartus II 64-Bit Version 12.1 Build 177 11/07/2012 SJ Web Edition
Revision Name caddr
Top-level Entity Name caddr
Family Cyclone IV GX
Device EP4CGX150DF31I7AD
Timing Models Final
Total logic elements 169,055 / 149,760 ( 113 % )
Total combinational functions 109,428 / 149,760 ( 73 % )
Dedicated logic registers 136,714 / 149,760 ( 91 % )
Total registers 136714
Total pins 27 / 508 ( 5 % )
Total virtual pins 0
Total memory bits 787,040 / 6,635,520 ( 12 % )
Embedded Multiplier 9-bit elements 0 / 720 ( 0 % )
Total GXB Receiver Channel PCS 0 / 8 ( 0 % )
Total GXB Receiver Channel PMA 0 / 8 ( 0 % )
Total GXB Transmitter Channel PCS 0 / 8 ( 0 % )
Total GXB Transmitter Channel PMA 0 / 8 ( 0 % )
Total PLLs 0 / 8 ( 0 % )

ソースは以下の修正が必要。

・caddr.v 74181.v 74182.v busint.v  memory.v rom.v を新規ファイルとしてプロジェクトに追加。(New Files... でVerilog-HDLを指定してコピペ) lm2clock.vは多分いらない。

・caddr.vのソース修正 `includeをすべてコメントアウト。プロジェクト内のモジュールを多重に読み込むことになるので。
・memory.vのソース修正 initial begin~end部分をコメントアウト。
・busint.vのソース修正 initial begin~end部分をコメントアウトし、always@(posedge clk)部分とalways@(rst_n)部分をalways@(posedge clk or negedge rst_n)として合体させる。

 あとはメモリを外に出す、caddr.vが大きすぎるのである程度のモジュールに分割し面積を減らせるか検討。特にパリティ回路はまるっと削除しても問題なさそう。あとはALUをまとめてしまう、など。

テスト用パワーLED(CRD付き)の試作メモ

24Vで70mA駆動のLEDをテストしたいのだが、ターゲットは高価なので代わりの物を作ってテストすることにした。

主要部品は以下、秋月電子より:
3W白色パワーLED OSW4XME3C1E 200ルーメン 
定電流源IC(30mA) NSI45030AT1G (10個入) 

パワーLEDはmax 700mAだが今回は70mA以下なので放熱板不要と判断。このLED、ロットによっては極性のマークがなかったりするらしい。定電流源ICはCRDじゃないのかな?
これらチップ部品を両面基板に半田付け。回路は以下の様な感じで。
2013LED 8

 外部に定電流源を繋ぐためにCRDはバイパスできるようにした。また、並列接続にすることにより電流を2倍にできる。
2013led80

2013led81

うおっ眩しい

Arduinoで4×4キーマトリックス

キーマトリックスのスキャンをやってみた。Arduinoのシールドにタクトスイッチを16個取り付け、4×4で扱う。
2013keyscan0

D9,D10,D11,D12は出力で、どれか1つをLOWにする。これをD5,D6,D7,D8で読み取り、キーが押されている位置を判定する。
2013keyscan

D9,D10,D11,D12の出力には2.2KΩの抵抗を入れている。これは複数のキーを押した時に出力のLOW-HIGHが直接繋がってしまうのを避けるため。
Arduinoのリファレンスによると、INPUTに指定したピンにHIGHを出力するとプルアップが有効になり、LOWで無効になるとあるので、この抵抗はいらなかったかも。 

スケッチはこちら。押したキーの番号を0〜15で返す。-1は何も押されていない。シリアルに出力する。
https://gist.github.com/houmei/4735235


int KO[4]={5,6,7,8};
int KI[4]={9,10,11,12};

void setup() {
  pinMode(KI[0],INPUT_PULLUP);
  pinMode(KI[1],INPUT_PULLUP);
  pinMode(KI[2],INPUT_PULLUP);
  pinMode(KI[3],INPUT_PULLUP);
  pinMode(KO[0],OUTPUT);
  pinMode(KO[1],OUTPUT);
  pinMode(KO[2],OUTPUT);
  pinMode(KO[3],OUTPUT);
  Serial.begin(9600);
  keyscan_init();
}

void loop() {
  int a;
  a=keyscan();
  if (a>=0) Serial.println(a);
}


void keyscan_init() {
  digitalWrite(KO[0],HIGH);
  digitalWrite(KO[1],HIGH);
  digitalWrite(KO[2],HIGH);
  digitalWrite(KO[3],HIGH);
}

int keyscan() { // pressed 0-15 , not pressed -1
  int i,j;
  int n=-1;
  for(i=0;i<4;i++) {
    for(j=0;j<4;j++) {
       if (i==j) {
          digitalWrite(KO[j],LOW);
       } else {
         digitalWrite(KO[j],HIGH);
       }
    }
    for(j=0;j<4;j++) {
      if (n<0 && digitalRead(KI[j])==LOW) {
        n=i+j*4;
      }
      delay(1); // wait for 1ms
    }
  }
  keyscan_init();
  return n;
}


Adafruit 1.8インチTFTシールド

スイッチサイエンスで扱っているAdafruit 1.8インチTFTシールドをとりあえず使ってみた。

Adafruit 1.8インチTFTシールド
(スイッチサイエンス)

Adafruit 1.8" 18-bit Color TFT Shield w/microSD and Joystick(Adafruit)

 ST7735R 128×160ドット 18bit色のディスプレイ、おおよそ33mm×40mmの大きさで、ウォークマンW用の液晶保護シートがぴったり貼れる。microSDカードスロット付き。上下左右と押しこむ操作のスティック付き。あと、バックライトを制御できそうなことが書いてあった(何もしないとON)。
 使用ピンはSPI接続でpin13,11,10,8。microSDカードを使う場合は加えて12と4。スティックはアナログ出力でA4。このシールドは3.3V/5V対応なのでGR-SAKURAに使えるかもしれん。

#define sclk  13  
#define mosi  11
#define sd_cs  4
#define lcd_cs 10
#define dc     8
#define rst    0  


 ライブラリはAdafruit-ST7735-LibraryとAdafruit-GFX-Libraryが必要。Adafruit-GFX-Libraryは同社のOLEDでも使われている。

https://github.com/adafruit/Adafruit-ST7735-Library

https://github.com/adafruit/Adafruit-GFX-Library

 これらをgithubのzipでダウンロードするボタンを押して、Arduino IDEのライブラリに展開すればいいんだけどそのままのフォルダ名だと半角英数字以外使えんといったエラーメッセージが出るので、-masterは削除しハイフン(-)はアンダースコア(_)に変えた。

 以下、ArduinoIDE1.0.3、MacOSX、Arduino UNO R3で確認。
2013tft1

 サンプルでついてくるshieldtestを開いて実行。スティックを動かすと画面に向きを表示。押しこむとmicroSDカードにあるparrot.bmpを開いて表示するらしいのだが、手元にないので適当に用意する。サンプルのparott.bmpを適当にリネームし、用意した128x160サイズのBMP画像のファイル名に合わせる(実際には128x171サイズ)。この時ファイル名は8+3文字の制限があるみたい。シリアルには以下の様に出力され、画像が液晶画面に表示される。

Button read analog = 3.34
Button read analog = 3.34
Button read analog = 0.59
Button read analog = 0.59
Button read analog = 3.34
Button read analog = 3.34
Button read analog = 3.34
Button read analog = 1.05
Initializing SD card...
Loading image 'sakura.bmp'
File size: 65718
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 128x171
Loaded in 1111 ms

2013tft2


こんな感じです。

DE0 QuartusIIのMegaWizardでPLLを使う

DE0の基板上のクロックは50MHz。搭載されているSDRAMは100MHzか133MHz動作なのでこれなんか必要だよなあPLLがあるはずだがどうやって使うんだろうと悩んでいたが解決した。
 これはメーカー/デバイスごと固有の設定であり、Verilog-HDLの記述でどうこうできる話ではない。 QuartusII(12.1sp1)では[Tools]→[MegaWizard Plug-in Manager]で呼び出す。
2013pll1
新規作成を選んで次へ。
2013pll2
ここでは出力する言語をverilog HDL、ファイル名はapll、使用するmegafunctionはI/O→ALTPLLを選択。
 2013pll3
ここからALTPLLの詳細設定画面。入力クロックは50MHzにする。
2013pll4
resetやlock信号は今回使わないのでチェックを外す。後はいくつか飛ばして以下の画面へ。
2013pll5
 c0~c4まで出力を設定できるが、ここではc0だけ。100MHzに設定。あとは飛ばす。
2013pll6
最終確認。[Finish]

メインの画面に戻って[File]→[Open...]でapll.bb.vを開く。以下の内容のダミーモジュールができる。

module apll (
	inclk0,
	c0);

	input	  inclk0;
	output	  c0;

endmodule
 これをつないでやれば良い。トップモジュールで定義したクロック入力をclk_50、PLLの出力をclkで分配すると
apll apll_0(clk_50,clk);
とすればよい。なおトップモジュールでクロック入力の名前を変えるとピンの対応付けが再度必要になるのでPinPlannerで定義する。これでチカチカ表示するのが二倍速になるのを確認した。

参考:
http://www.emb4fun.de/fpga/nutos1/

昔話:
昔はのう、クロック入力を分周してデューティ50%で使ってたんじゃ。例えば内部50MHz動作だと100MHzの発振器が必要で、当時CMOSでそんな出力のはなかったんでECLレベルの発振器を使っておったんじゃ……
記事検索
プロフィール

hardyboy

カテゴリ別アーカイブ
月別アーカイブ
QRコード
QRコード
  • ライブドアブログ