A2PDP11 (8) コンソール ODT への入力
前回、コンソール ODT の出力ができるようになりましたが、ALE にノイズがのる現象が出ていました。ブレッドボードから、ワイヤーラッピングに変更したり、ダンピング抵抗を入れてみたりしましたが、改善せず。一旦諦めて、ソフト的な対処でしのぎます。
下図に、ノイズ発生時のキャプチャを示します。オレンジマーカーのタイミングで、ALE が一瞬 HIGH になっています。特に、17777566 (XBUF) アクセス時に、頻発します。
top.sv を修正します。ALE がアサートしてからのクロック数をカウントし、0 のときだけ DAL をラッチするようにしました。
logic [7:0] count;
always_ff@(posedge clk) begin
if (!ale_n) begin
count <= count + 1'b1;
end else begin
count <= 0;
end
end
logic [21:0] mdal;
logic [3:0] maio;
logic [1:0] mbs;
always_ff@(negedge ale_n) begin
if (count == 0) begin
mdal <= {dal_hi, dal_lo};
maio <= aio;
mbs <= bs;
end
end
Tang Nano 9K および Arduino との接続を変更します。
ODT の送受信データは、レベル変換 IC を介して、Arduino と繋いでいます。
レベル変換は、SN74LVC245AN を使いました。3.3V 電源でも、5V 入力が可能です。
Arduino のスケッチを修正します。
D2-D9 は、ODT 入出力データです。
DIR は、SN74LVC245AN のデータ方向切り替えで、Arduino と Tang Nano 9K 間のデータ送受信方向を示します。
LOW の時、Tang Nano 9K から Arduino(ODT 出力データ)
HIGH の時、Arduino から Tang Nano 9K(ODT 入力データ)
OE は、SN74LVC245AN の出力イネーブル信号(負論理)です。
RRDY(Read Ready)は、Arduino がデータを受信可能なとき HIGH になります。
RSTB(Read Strobe)は、Tang Nano 9K からの出力があるとき HIGH になります。
WRDY(Write Ready)は、Arduino から送信データがある時 HIGH になります。
WSTB(Write Strobe)は、Tang Nano 9K が Arduino からのデータ受信待ちの時 HIGH になります。
// ODT serial console interface
// TEST 5: 2024.08.10 Read ODT console out, nanja.info
// TEST 6: 2024.08.25 Read/Write ODT console, nanja.info
#define d0_pin 2
#define d1_pin 3
#define d2_pin 4
#define d3_pin 5
#define d4_pin 6
#define d5_pin 7
#define d6_pin 8
#define d7_pin 9
#define dir_pin 10 // LOW = Read from DCJ11, HIGH : Write to DCJ11
#define oe_n_pin 11 // ODT data enable
#define rrdy_pin 12 // Ready to read from DCJ11's ODT data
#define rstb_pin 13 // Strobe for read from DCJ11's ODT data
#define wrdy_pin 14 // Ready to write to DCJ11's ODT data
#define wstb_pin 15 // Strobe for write to DCJ11's ODT data
void setup() {
Serial.begin(9600);
pinMode(d0_pin, INPUT);
pinMode(d1_pin, INPUT);
pinMode(d2_pin, INPUT);
pinMode(d3_pin, INPUT);
pinMode(d4_pin, INPUT);
pinMode(d5_pin, INPUT);
pinMode(d6_pin, INPUT);
pinMode(d7_pin, INPUT);
pinMode(rrdy_pin, OUTPUT);
pinMode(rstb_pin, INPUT);
pinMode(wrdy_pin, OUTPUT);
pinMode(wstb_pin, INPUT);
pinMode(dir_pin, OUTPUT);
pinMode(oe_n_pin, OUTPUT);
digitalWrite(rrdy_pin, HIGH);
digitalWrite(wrdy_pin, LOW);
digitalWrite(dir_pin, LOW);
digitalWrite(oe_n_pin, HIGH);
Serial.println("Serial Start");
}
void loop() {
static byte rdata; // read from DCJ11's ODT data
static byte wdata; // write to DCJ11's ODT data
if (digitalRead(rstb_pin)) {
digitalWrite(dir_pin, LOW);
pinMode(d0_pin, INPUT);
pinMode(d1_pin, INPUT);
pinMode(d2_pin, INPUT);
pinMode(d3_pin, INPUT);
pinMode(d4_pin, INPUT);
pinMode(d5_pin, INPUT);
pinMode(d6_pin, INPUT);
pinMode(d7_pin, INPUT);
digitalWrite(oe_n_pin, LOW);
bitWrite(rdata, 0, digitalRead(d0_pin));
bitWrite(rdata, 1, digitalRead(d1_pin));
bitWrite(rdata, 2, digitalRead(d2_pin));
bitWrite(rdata, 3, digitalRead(d3_pin));
bitWrite(rdata, 4, digitalRead(d4_pin));
bitWrite(rdata, 5, digitalRead(d5_pin));
bitWrite(rdata, 6, digitalRead(d6_pin));
bitWrite(rdata, 7, digitalRead(d7_pin));
digitalWrite(oe_n_pin, HIGH);
digitalWrite(rrdy_pin, LOW);
Serial.write(rdata);
digitalWrite(rrdy_pin, HIGH);
} else if (digitalRead(wstb_pin)) {
digitalWrite(dir_pin, HIGH);
pinMode(d0_pin, OUTPUT);
pinMode(d1_pin, OUTPUT);
pinMode(d2_pin, OUTPUT);
pinMode(d3_pin, OUTPUT);
pinMode(d4_pin, OUTPUT);
pinMode(d5_pin, OUTPUT);
pinMode(d6_pin, OUTPUT);
pinMode(d7_pin, OUTPUT);
digitalWrite(d0_pin, bitRead(wdata, 0));
digitalWrite(d1_pin, bitRead(wdata, 1));
digitalWrite(d2_pin, bitRead(wdata, 2));
digitalWrite(d3_pin, bitRead(wdata, 3));
digitalWrite(d4_pin, bitRead(wdata, 4));
digitalWrite(d5_pin, bitRead(wdata, 5));
digitalWrite(d6_pin, bitRead(wdata, 6));
digitalWrite(d7_pin, bitRead(wdata, 7));
digitalWrite(oe_n_pin, LOW);
digitalWrite(wrdy_pin, LOW);
} else {
if (Serial.available() > 0) {
wdata = Serial.read();
digitalWrite(wrdy_pin, HIGH);
}
digitalWrite(oe_n_pin, HIGH);
}
}
top.sv の ODT の出力(XBUF)を Arduino に転送する部分を修正します。
rxrdy は DCJ11 の XCSR の done フラグで、HIGH の時、ODT の出力を処理できることを示します。
rrdy1 は、CLK に同期した、RRDY 信号です。
rstb は、Tang Nano 9K から Arduino への転送待ちを示します。
rdata は、ODT の出力データです。
ad は、Arduino との入出力データ接続ラインです。
ODT の出力(XBUF への書き込み)を rdata にラッチし、RSTB を HIGH します。同時に、rxrdy を LOW にして、ODT の次の出力を抑制します。
Arduino が受信すると RRDY が LOW になるので、RSTB を LOW にします。
受信が完了したら、rxrdy を HIGH にし、ODT の次の出力を受け付けるようにします。
バスリセット(GP CODE = 014)時に、rxrdy と RSTB をリセットするようにしました。
logic rxrdy;
logic rrdy1;
logic rrdy0;
logic [7:0] rdata;
always_ff@(negedge clk) begin
rrdy0 <= rrdy;
rrdy1 <= rrdy0;
end
always_ff@(negedge clk) begin
if ((sctl_n == 0) && (mdal == XBUF)) begin
rstb <= 1'b1;
rxrdy <= 1'b0;
rdata <= dal_lo[7:0];
end else if (!rrdy1) begin
rstb <= 1'b0;
end else if (!rstb) begin
rxrdy <= 1'b1;
end
if (gp_code == 8'o014) begin
rxrdy <= 1'b1;
rstb <= 1'b0;
end
end
assign ad = rstb ? rdata : 8'bz;
Arduino から、Tang Nano 9K へのデータ転送部を実装します。
wxrdy は、RCSR の done フラグで、HIGH の時、ODT への入力データがあることを示します。
wrdy1 は、CLK に同期した、WRDY 信号です。HIGH の時、Arduino から送信するデータがあることを示します。
wstb は、Tang Nano 9K から Arduino へのデータ転送待ちを示します。
wdata は、ODT への入力データです。
Arduino から出力データがある時(wrdy1 = HIGH)、WSTB を HIGH にし、データ転送待ち状態にします。
ad から wdata にデータをコピーし、WSTB を LOW にします。同時に、wxrdy を HIGH にして、DCJ11 に、ODT 入力があることを伝えます。
RBUF の読み取りを確認し(mdal == RBUF)、wxrdy を LOW にします。
バスリセット(GP CODE = 014)時に、wxrdy と WSTB をリセットします。
logic wxrdy;
logic wrdy1;
logic wrdy0;
logic [7:0] wdata;
always_ff@(negedge clk) begin
wrdy0 <= wrdy;
wrdy1 <= wrdy0;
end
always_ff@(negedge clk) begin
if (wrdy1) begin
wstb <= 1'b1;
end else if (wstb) begin
wdata <= ad;
wstb <= 1'b0;
wxrdy <= 1'b1;
end else if (mdal == RBUF) begin
wxrdy <= 1'b0;
end
if (gp_code == 8'o014) begin
wxrdy <= 1'b0;
wstb <= 1'b0;
end
end
BUFCTL のアサート(LOW)時の、ODT インターフェースへの応答を修正します。
受信制御・状態レジスタ RCSR(17777560)の読み出しに対し、wrdy を返します。
送信制御・状態レジスタ XCSR(17777564)の読み出しに対し、rxrdy を返します。
受信バッファレジスタ RBUF(177777562)の読み出しに対し、wdata を返します。
それ以外の読み出し時は、odt_out をハイインピーダンスにし、dal_out を返します。
logic [15:0] dal_out;
logic [15:0] odt_out;
assign dal_lo = bufctl_n ? 16'bz : dal_out | odt_out;
always_ff@(negedge bufctl_n) begin
if ((maio == DATA_READ) && (mbs == BS_EXT)) begin
if (mdal == RCSR) begin
odt_out <= {8'b0, wxrdy, 7'b0};
end
if (mdal == XCSR) begin
odt_out <= {8'b0, rxrdy, 7'b0};
end
if (mdal == RBUF) begin
odt_out <= wdata;
end
end else begin
odt_out <= 16'bz;
end
end
コンソール ODT の動作を確認します。
下図は、<CR><LF>出力時の様子です。オレンジマーカー部で、XBUF に 015 <CR> が書き込まれます。赤マーカー部で、RRDY が LOW になり、Arduino がデータを受信したことがわかります。白マーカー部で RRDY が HIGH になり、Arduino のシリアル出力が完了し、次のデータ受信が可能になったことがわかります。
数は、'0' を入力した時の様子です。
赤マーカー部で、WRDY が立ち上がり、Arduino から送信データがあることがわかります。オレンジマーカー部で、ad に '0'(060)が出力され、黄色マーカー部で、WRDY が LOW になり、データが wdata に取り込まれます。白マーカー部は、エコーバック出力を示します。
コンソール ODT の入出力ができるようになりました。
数は、R0 レジスタに 123456 を書き込む様子です。
次はメモリを実装します。
参考文献
DCJ11 Microprocessor User's Guide, 5.3 CONSOLE ODT, 1983
この記事が気に入ったらサポートをしてみませんか?