RAMがほしい。
regを使ってRAMを作れないことはないんだけど、それだとロジックセルのフリップフロップを使ったRAMになって、せっかくチップに64KB近いRAMが載っているのがもったいない。
8MバイトのSDRAMもあるのだけど、これは扱うのはちょっとめんどくさそうなのであとまわし。
ということで、チップ内蔵RAMを使ってみる。
ToolメニューのMega Wizardというところからメモリモジュールが作成できるらしい。
いろいろな種類のRAMが選べるのだけど、今回はとりあえずRAM:1-PORTを選ぶ。
インタフェース
「q output port」は、レジスタ経由の受け渡しになって1相遅れるらしいので、ここではチェックをはずしておく
メモリ書き込み時の出力を選ぶ。書き込んだ値か古い値かなどが選べるけど、ここでは書き込んだ値にしておく。
メモリの初期化。値を設定しておくこともできるけど、今回は使わない。
最後に、生成ファイルの選択。ここで、_instを選ぶとメモリアクセスのサンプルが出力されるので、使い方がわからないうちは選んでおくといい。
そしたら、コードを書く。
今回は、左4つのスイッチをアドレス直結しつつ一番左の7セグに直結、右4つのスイッチをメモリへのデータ入力と一番右の7セグに直結、あとはメモリ出力を右から2番目の7セグに直結して、左端のボタンを押すと書き込み信号が出るような、あまり賢くない回路を組んでみた。
なので、左4つのスイッチで指定したアドレスの値が常に右から2番目の7セグに表示される。ボタンを押すと指定したアドレスに右4つのスイッチで指定した値が書き込まれる(同時に読み込まれるので右から2番目の7セグにも反映される)。という動きをする。
いままで組んだ回路は状態を覚えてくれていなかったのだけど、これでいろんな状態を管理できるようになった。
楽しい。
見てる側には、表示が7セグとLEDしかないと、何も変わり映えしないので、楽しさは伝わりにくいだろうけど。
コードはこんな感じ。hexsegは7セグ表示のモジュールを適当に。
module sram( input clk, input [9:0] sw, input [2:0] btn, output [9:0] led, output [7:0] hled0, output [7:0] hled1, output [7:0] hled2, output [7:0] hled3 ); assign led=10'h0; assign hled2=8'hff; // chattering reg [15:0] cnt; reg ubtn; always @(posedge clk) begin cnt=cnt+1; end always @(posedge cnt[15]) begin ubtn=btn[2]; end // button reg obtn;// old button reg wsig;// write signal always @(posedge clk)begin if(ubtn) begin if(!obtn) begin obtn <= 1'b1; wsig <= 1'b1; end else begin wsig <= 1'b0; end end else begin obtn <= 1'b0; end end // ram access wire [7:0] rdata; ram ram_inst ( .address ( {1'b0, sw[9:6]} ), .clock ( clk ), .data ( {4'd0, sw[3:0]} ), .wren ( wsig ), .q ( rdata ) ); // display hexseg h1(clk, sw[3:0], hled0); hexseg h2(clk, rdata[3:0], hled1); hexseg h3(clk, sw[9:6], hled3); endmodule