パスワードを忘れた? アカウント作成

kitune-sanさんのトモダチの日記みんなの日記も見てね。 Idle.srad.jpは、あなたの人生において完全な時間の浪費です。見るなよ、見るなよ。

16209293 journal
日記

kitune-sanの日記: Chisel

日記 by kitune-san

久しぶりの日記

コロナの濃厚接触者になってしまい、会社に出社できなかったので、
今日は積読していた「RISC-VとChiselで学ぶはじめてのCPU自作」を読んで(コードの写経)をしていた。

テストの出力と脳内デバッグ結果とが一致しなくて第8章あたりで手が止まってしまっていた。
で、「:=」がVerilogでいうノンブロッキング代入のことだと思っていたが、そうではなく、ただの信号間の接続だということに気がついた。
一旦思い込んでしまうと、思い込みを解消するまで大変だ。やっとスッキリした。

alwaysやprocessといった記述がないのでここでレジスタに代入しているんだぞって感じがなく、今の時点では読みにくいなぁと思ってしまう。
これは馴れが必要だ。

15554599 journal
日記

kitune-sanの日記: 今更だけど、サイバーパンク2077クリアした

日記 by kitune-san

クリアと言ってもメインストーリーのクリアだけど。決して実績100%とかではない。
今日3回アダムスマッシャーを倒した。
なんというか・・・バッドエンドではないけど、ハッピーエンドでもないなこれ。

個人的に印象に残ってるクエストは
・デラマン
・ブレンダン
・ペラレス
・ケンタウロスーアルファー星人のー仕業だー
かなぁ

15535804 journal
日記

kitune-sanの日記: DDR4 SPDの読み書きがしたい!

日記 by kitune-san

フリーソフト使えばいいじゃんと思ったあなた!そのとおりなので戻るボタンを押しましょう。

マイXMPをメモリに書き込んで自分専用のオーバークロックメモリを作ろうと思ったことはありませんか?私はありません。
ただ、SPD設定を意味もなく読み書きしたいなとふと思ったのです。
いろいろ調べているとセンチュリーマイクロが販売しているみたいだけれども、個人が買える感じではない。
そもそもフリーソフトでSPD書き換えができるのだけれども、どれが本家かわからん。そして怖い。あとなにより面白くない。
というわけで基板から作ってみることにした。

実際、ちょっと変わったEEPROMと接続するだけなので、回路はそんなに難しくない。EEPROMの資料はSPD EEPROMとかで検索すると出てくる。
回路図はこれ(笑)。KiCAD使おうと思ったけど、部品作成からする必要があり面倒だったので手で書いた。
マイコンは練習も兼ねてRaspberry pi picoにした。
面倒なのはEEPROMの電源は仕様上は2.5V±10%だということで、3.3Vから降圧する必要がある。(いくつかのSPD EEPROMのデータシートとか見るとそのまま3.3Vぶっ込んでも問題はなさそうである。)
LDOレギュレータ使うかツェナーダイオード使うか迷った末、LDOレギュレータ(BH25MA3)を使用することにした。
表面実装なのはパーツ屋にあった2.5VLDOレギュレータがこれしかなかったため。普通に3本足のものとかあるのでそちらを使うことをおすすめする。だれもやらないと思うが。

完成図はこれ
パーツを外したときの上からの写真
はんだ面

プログラムはC/C++で書いた。Pico-SDKめっちゃ楽。クラスを使ったのは、久しぶりのC++を体験したかったから。それだけ(普段はC言語)。だからC++できているかはわからん。
最後にC++触ったのって、いつだろう。shared_ptrが標準に入るとか入らないとか言ってたころだと思う。

SPD読み出しの出力はこんな感じ。
書き込み機能もつくったけどまだ確認できてない。

コードは以下に記録した。
https://github.com/kitune-san/SPD_RW

15497658 journal
日記

kitune-sanの日記: PCケース変更 4

日記 by kitune-san

CoolerMaster Silencio 650からFractal Design Define R5に変更
ええ、好きですとも静音と窒息型。

というか、側面スケスケケース多すぎてびっくり。流行ってるのか。
きれいな配線と光らせる自信ががないよ。

15461771 journal
日記

kitune-sanの日記: 下側が可動する小型のLANポートあるじゃん? 4

日記 by kitune-san

意識していないとたまーに、
あそこにUSB(タイプAオス)を突っ込んじゃうんだけど、なんかいい対策ないかな。

え、そんなことしたことないって?ほんとに〜?

15449860 journal
日記

kitune-sanの日記: 8086マイクロコードの読み方 6

日記 by kitune-san

2021/10/24 改めて読み返すと勘違いがいくつもあり、間違っている。とてもいいコメントをもらっており、消すのはもったいないので日記を残しておくが、日記の内容自体は参考にならないため注意。

------
8086のマイクロコードってどうなんているんだろうと思って調べていたら、メタルレイヤの画像から読み出している人がいてびっくり。
せっかくなのでマイクロコードを読めるように少しだけ調べてみた。
まだ少しだけしか読めていないけれど、自分の備忘録として残しておく。

読んでくれる人がいるかどうか微妙だが…もしも間違いなどを見つけたら忌憚なく教えてほしい。でも優しく教えてね。

理解するのに重要な資料はUS patent 4363091。ここに必要なこと全て書いてあると思う。
ただし、ここに書いてあることが8086/88と完全に一致していない可能性があることを考慮に入れておく必要がある。

前半はCPUのハードウェア的な説明と一部命令の説明が延々と続く。レジスタ、ALU、フラグの関係を理解していれば読む必要がないと思う。最終ページにあるFig.1〜3を必要に応じて参照する。
マイクロコードに関する詳細な記述は、27ページ目(PDFで15ページ目)のTABLE 7の上の「The microcode routines for〜」からである。

マイクロコードは21ビットで構成されている。この21ビットには前半10ビットと後半11ビットとで2種類の操作命令が格納できるようになっている。
ただし今回の説明では、実際のコードやビット配置については追求しない。自分もまだよくわかっていない。
なのでニーモニックから読み取ることを目標とする。

マイクロコードの構成は次のようになっている。
S/D: レジスタやALUとの転送操作を行う。
Typ/a/b/F: 転送以外の操作(ALU操作やアドレスジャンプ)を行う。
つまり、データ転送動作とALU操作(他、操作命令)を同時に行うことができる。

さて、ここまで来たところで実際にマイクロコードを読んでみよう。
読み取る内容はAAA/AAS命令のマイクロコード列である。

 AR  X 7 6 5 4 3 2 1 0 CR S    D      Typ  a    b     F
 ------------------------------------------------------
 AAA 0 0 0 1 1 X 1 1 1 0  A    tempaL  1   XI   tempa
 AAS                   1  ONES tempb   1
                       2  Σ    A       1   DEC  tempb F
                       3               0   XΦ   5
                       4               1   INC  tempb
                       5  X    tempb   0   NCY  7
                       6  Σ    X       4   none RNI
                       7               4   none RNI

うまく表示できないので、等幅のメモ帳に貼り付けるか、US patent 4363091の「TABLE 7」を見てほしい。
テーブルが使えないっぽい。

表のARは外部のROMから読み取られた(ARレジスタに格納された)命令とそのビット列を示している。このARレジスタの値を元にマイクロコードが記述されたアドレスをデコードする。
CRはマイクロコードを進めるたびにインクリメントされるレジスタの値を示している。ジャンプ先の指定などで使用する。結果として相対アドレスに近い感じになっている。

では、いってみよう。

まず最初の命令(CR=0)を読んでみる。S=A, D=tempalとあり、Aレジスタの内容をtempaの下位へコピーする。
次にa=XI, b=tmpaとある。これは、1stオペランドにtmpaを指定したXI操作をALUに指定する。これはType1の指示である。なお、Fig.1bより、ALUの第二オペランドはtempb固定であることがわかる。
(実は、資料の方ではb=temp2と記載があったのだが、temp2なぞここ以外見当たらなかった。リバースエンジニアされた方の資料にはtempaと書かれていたためこちらに差し替えた)

A->tempaL

tempa -> ALU(XI) -> Σ
tempb --/

注意する点として、ALUの操作指示は指示後次のコード読み取りに入ったとしても、別のALU操作指示(TYPE1指示)がくるまではその指示状態が維持されるということがある。これを頭に入れておかないと後のINC/DECで混乱する。

XI命令のALU動作は、Fig.2に示されている。AASの場合のマイナスはどこで指定されるのか記載がなく、実は私の中で疑問が残っているが、とりあえず今回は無視して読み進める。

2つめの命令(CR=1)へ進む。S=ONES, D=tempbとあり、ONESをtempbへコピーする。ONESというのは資料を見た感じでは6のようだ。つまりXI命令の第二オペランドはここで設定される。

ONES(6) -> tempb

tempa -> ALU(XI) -> Σ
tempb --/

3つめの命令(CR=2)へ進む。S=Σ, D=Aとある。これはALU(XI)の演算結果をAレジスタへ格納することを示している。
また、Fのフラグが立っていることが確認できる。これは、ALU(XI)の演算で生じたフラグ変化を記録することを示している。

tempa -> ALU(XI) -> Σ -> A
tempb --/       \-> Σ(F) -> flags

同時に、a=DEC, b=tempbの指示がある。これはtempbのデクリメントを指示する。これによりALUはXIからDECへ切り替わる。

tempb -> ALU(DEC) -> Σ

4つめの命令(CR=3)へ進む。a=XΦ, b=5とある。これはMレジスタの下位ビット---ARレジスタの3ビット目を検査し真であればCR=5まで移動させるというタイプ5の指示である。
3ビット目は一体何かというと、このビットによってAAA/AAS命令のどちらであるかを決定している。

ではまずAAAの場合(XΦの結果が偽であった場合)を考える。

5つめの命令(CR=4)では、a=INC, b=tempbが指定されている。これによりALUはDECからINCへ切り替わる。

tempb -> ALU(INC) -> Σ

6つめの命令(CR=5)では、S=X, D=tempbとある。これは、Xレジスタの内容をtempbの下位へコピーする。

X -> tempb
tempb -> ALU(INC) -> Σ

また同時にキャリーフラグの検査を行う。キャリーフラグは3つめの命令(CR=2)のときに格納したflagsで立つことがある。ざっくり条件を書くと、6を足した(AAAの場合)計算結果が9を超えた場合である。
キャリーフラグが立っていない場合はCR=7まで移動する。CR=7の命令はRNI(Run Next Instruction)となっておりマイクロコードの終了を示す。そうでなければ次の命令へ進む。

7つめの命令(CR=6)では、S=Σ, D=Xとある。これは、これはALU(INC)の演算結果をXレジスタへ格納することを示している。

tempb -> ALU(INC) -> Σ -> X

同時にRNI司令が入り、マイクロコードの実行を終了する。

次に、AASの場合(XΦの結果が真であった場合)を考える。

飛び先の6つめの命令(CR=5)では、S=X, D=tempbとある。これは、Xレジスタの内容をtempbの下位へコピーする。注目する点は、AAAと違いALCがDECの状態が継続していることである。

X -> tempb
tempb -> ALU(DEC) -> Σ

また同時にキャリーフラグの検査を行う。キャリーフラグは3つめの命令(CR=2)のときに格納したflagsで立つことがある。ざっくり条件を書くと、6を引いた(AASの場合)計算結果が9を超えた場合である。
キャリーフラグが立っていない場合はCR=7まで移動する。CR=7の命令はRNI(Run Next Instruction)となっておりマイクロコードの終了を示す。そうでなければ次の命令へ進む。

7つめの命令(CR=6)では、S=Σ, D=Xとある。これは、これはALU(DEC)の演算結果をXレジスタへ格納することを示している。

tempb -> ALU(DEC) -> Σ -> X

同時にRNI司令が入り、マイクロコードの実行を終了する。

以上がAAA/AAS命令のマイクロコードである。他の命令も読めそうな気がしてこない? 読める・・・読めるぞ・・・!

15437636 journal
日記

kitune-sanの日記: SDRAMコントローラをSystemVerilogで書いてみる

日記 by kitune-san

FPGA内部のRAMブロックだけでは今後容量が不足してくると思えるため、DE0-CVに実装されているSDRAM(IS42S16320F-7TL (32Mx16))へアクセスするコントローラを作ることにした。

最初は、CPU側からのアクセスのみを考えていて、シングルモードの読み書きで問題ないと考えていた。
しかし途中でビデオメモリとの共用をしたくなってきた。共用すると速度の問題からVRAM用のキャッシュが必要となり、複数バイトの連続読み出しが必要になった。
出てきた案は、
1. バースト書き込み, バースト読み出しモードを使用する。
2. シングル書き込み, バースト読み出しモードを使用する。
3. シングルの読み書きモードとし、ACK後にREAD/WRITEコマンドを連続して送信する。(毎回バンクとCOLアドレスを指定)

1の案は、バーストの読み出し回数が固定の上、書き込みは1回としたいため、廃案にした。
2の案は、当初最有力であったが、バーストの連続読み出し回数が最大8回であることと、後に3のアクセス方法を見つけたため、廃案とした。
3の案は、読み書き回数が都度指定可能で、さらに8回以上(最大1023回)連続読み出しができるのでこれを採用した。なんかデメリットがあるかもしれないけど、とりあえずこれで進めた。

で、作ったのがこれ
まだ実際にFPGAに書き込んで動作は見ていない。どうやって確認しようか考え中。シュミレータで信号の確認はした。

使い方は次のようにした、
1. アクセスをしたいアドレス(address)、連続アクセス回数(access_num)、(書き込みの場合は)1バイト目の書き込みデータ(data_in)をセットする。
2. 読み書きどちらかの要求フラグ(write_request/read_request)を立てる。

書き込みの場合
3. 書き込み確認フラグ(write_flag)が立ったことを確認したら、要求フラグを下げ、次の書き込みデータをdata_inにセットする。
4. write_flagが下がるまで、次の書き込みデータをdata_inにセットし続ける。

読み取りの場合
3. 読み取り確認フラグ(read_flag)が立ったことを確認したら、要求フラグを下げ、data_outからデータを取得する。
4. read_flagが下がるまで、次の読み取りデータをdata_outからデータを取得する。

注意点として、colアドレス(IS42S16320Fの場合アドレス末尾10バイト)と書き込み回数とを足した結果が、colアドレスのアドレス表現を超える場合には、
書き込み/読み取り途中でアクセス先が折り返される。
また、読み書き処理中に、address, access_numは、変更禁止である。

---

CPU(XTバス)からの読み書き要求とビデオコントローラからの読み取り要求の調停処理は、このコントローラより上のレイヤで作製しようと思う。

15432398 journal
日記

kitune-sanの日記: PC/XTのREADY信号 2

日記 by kitune-san

PC/XTの回路図SystemBord(2/10)は、ざっくり分けると
1. READY信号の生成(nRDY/WAIT, RDYTODMA)
2. DMA要求発生時の信号生成 (HLDA, AENBRD, /AEN, DMAWAIT, /DMAEN)
3. NMI信号生成
4. I/OCHECK信号生成
5. DMA用クロック信号生成(H幅の伸張) (DCLK)
に分かれると思うのだけれど、この内「1. READY信号の生成」がわかりにくくて理解するのに時間がかかってしまったため忘れる前にメモする。というか今でもあれ?となる。

まず、nRDY/WAIT信号は8284のnAEN1に入力される信号で、CPUへ送信するREADY信号を生成するために使用される。nRDY/WAIT=HでREADYはLOW(CPUはT3->Twステート)となる。
nRDY/WAIT信号は一つのフリップフロップから出力される。このFFのトリガはクロックではなく下記のの信号の論理の組み合わせとなっている。
¬/XIOW + ¬/XIOR + (/DACK0BRD ・ ¬/XMEMR ・ AENBRD)
※ AENBRDはLのときアドレスイネーブルとなることに注意
上記の入力がL->Hとなると、nRDY/WAIT=Lとなる。ただし、後述のCLR信号により、CPUクロックの立ち上がりエッジでHにもどる。
FFのPRにはI/OCHRDYが、CLRにはnRDY/WAITを入力としたもう一つのFF(クロック立ち上がりエッジ)の出力/Qが接続されている。
I/OCHRDY信号はバスを通して外部から制御でき、適切なアクセスタイミングでLOWに落とすことで外部のカードからREADY信号を要求することができる。

以上の情報から、nRDY/WAIT信号が発生する条件は以下のタイミングとなる。
1. I/Oアクセス直後 (/XIOWまたは/XIORが、H->Lとなった時)
2. 外部のカードがREADY要求している。
3. DACK0以外のDMAアクセス発生時 (・・・多分)

1,2はわかりやすいと思うのだけれども、3についてはわかりにくいと思う。そもそも、DMAの信号でも、/XIOWか/XIORどちらかがLとなるから(/DACK0BRD ・ ¬/XMEMR ・ AENBRD)いらなくね?と1日中考えていた。
それで、8237のデータシートを見ていたら、8237の書き込み信号は拡張設定をしなければ読み取り信号が出力されるタイミングよりも1クロックずれるということに気がついた。
つまりこの設定がなければ、/XMEMR=L, /XIOW=LのDMA動作の場合に本来8237がほしいタイミングでREADY信号(REDYTODACK)が来ないことになる。これを回避したかったのだろう。…ということで納得することにした。
DACK0を除いたのは、DACK0はDRAMリフレッシュですでに使用されており、不要だったのだろう。

で、これをFPGAで動かせるように実装してみたいと思ったのだが、FFのトリガがクロック以外であることに気が付き困ってしまった。
FPGAを最初に触った時、クロック以外の信号をトリガに入れまくってよくわからなくなったトラウマがあるため避けたい。少なくとも(どっちのエッジでもいいからとりあえず)クロック同期にしたかった。
で、アイディアとして8284内部の立ち上がりエッジのFFを取り出し(イメージ的にはこれをCLR信号のFFと統合して)、オリジナルのnRDY/WAIT信号生成FFを置き換えできないかと考えた。
で、作ったのがこれ。シュミレータで見た感じは思い通りになっている・・・と思う。

15425876 journal
日記

kitune-sanの日記: 8237をSystemVerilogで書いてみる #2 (終)

日記 by kitune-san

前回から、新しく2つのブロックを追加した。
KF8237_Address_And_Count_Registers.sv - アドレスレジスタと現在カウントレジスタの計算を行うブロック。
KF8237_Timing_And_Control.sv - DMA制御のための信号出力を行うブロック。
これらを配線し、KF8237.svを作成した。
実のところ、すべての実装が完了しているわけではなくメモリ間転送については未実装のままとなっている。途中まで忘れていた。現状欲しい機能は実装できているのでとりあえず終了する。

・・・これでPC/XTを構成する主要なチップを、CPUを除いてFPGAで実装することができた。次はラスボス(8088)だ。
mod r/wとかややこしいし、8080からやったほうがいいのかなぁ。

15416473 journal
日記

kitune-sanの日記: 8237をSystemVerilogで書いてみる #1

日記 by kitune-san

8237AはDMAのチップだ。

ここまでで2つのブロックを作成した。
KF8237_Bus_Control_Logic.svは、内部バスの書き込み/読み取り信号を生成するブロック。
KF8237_Priority_Encoder.svは、DMA要求の優先度解決と優先度の回転を行うブロック。

優先度の回転処理は、KF8259と同じで、
ビット右回転→優先度解決→ビット左回転 という手順となっているが、もっといい方法があるような気がする。

オリジナルのデータシートのブロック図は自分にはわかりにくくて、そのまま真似して実装できそうになかった。
「PRIORITY ENCODER AND ROTATING PRIORITY LOGIC」からは、外部信号としてDACQ0-3、HLDA、HRQ、DACK0-3が出ているけど、
今回のKF8237_Priority_Encoder.svでは、DACQ0-3入力以外の信号処理は作らなかった。

次は、ステートマシンとモードに応じた信号の出力ブロックを作っていいこうと思うが、どんな構成にしようかな・・・。

typodupeerror

日々是ハック也 -- あるハードコアバイナリアン

読み込み中...