トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

stackm.v

ブロックRAMを用いたスタック

パラメータ

パラメータ名 既定値
AWIDTH 10 ブロックRAMのアドレス幅 
N 1024 スタック(ブロックRAM)の要素数

入出力ポート

  ポート名 既定値  
入力 clk 1 グローバルクロック
入力 reset 1 グローバルリセット
入力 load 1 1のときclkの立ち上がりでスタックトップにdの値を書き込み
入力 push 1 1のときclkの立ち上がりでスタックをプッシュ
入力 pop 1 1のときclkの立ち上がりでスタックをポップ
入力 pop2 1 1のときclkの立ち上がりでスタックを2つポップ(ポップ2回分)
入力 thru 1 1のときthruをqtopに出力
入力 d 16 スタックトップに書き込む値
入力 dthru 16 thruが1のときdthruをqtopに出力
出力 qtop 16 thruが1のときdthru,0のときスタックトップの値
出力 qnext 16 スタックの2番目の値

PUSH命令(メモリから読み出したデータをスタックにプッシュ)を1クロックサイクルで実行するために,thruとdthruを導入.
メモリから読み出すのに1サイクル必要で,その読み出したデータをスタックトップに書き込むのにさらに1サイクル必要となる.そこでスタックに書き込むかわりに,メモリからの読み出しデータをdthruに入力し,それをスタックトップqtopの値とする.つまり,フリップフロップq[0]に書かれているスタックトップの値をスルーして,メモリの出力をスタックトップqtopとして出力する.

ソースコード

module stackm(clk, reset, load, push, pop, pop2, thru, d, dthru, qtop, qnext);
parameter AWIDTH = 10, N = 1024;

  input clk, reset, load, push, pop, pop2, thru;
  input [15:0] d, dthru;
  output [15:0] qtop, qnext;
  reg [AWIDTH-1:0] ptop, ptopf, addra, addrb;
  reg [15:0] mem [N-1:0];
  reg [15:0] qtopf;
  wire [15:0] pnextf;
  wire thruwrite;

  always @(push or pop or pop2 or ptop)
  if(push) ptopf = ptop - 1;
  else if(pop) ptopf = ptop + 1;
  else if(pop2) ptopf = ptop + 2;
  else ptopf = ptop;

  always @(posedge clk or negedge reset) 
  if(!reset) ptop <= 0;
  else ptop <= ptopf;

  assign  pnextf = ptopf + 1;
  assign thruwrite = !(push||pop) && thru;

  always @(load or thruwrite or d or dthru)
  if(load) qtopf = d;
  else if(thruwrite) qtopf = dthru;
  else qtopf = 16'hxxxx;

  always @(posedge clk)
  begin
    if(load || thruwrite) mem[ptopf] <= qtopf;
    addra <= ptopf;
  end

  always @(posedge clk)
  begin
    if(push && thru) mem[pnextf] <= dthru;
    addrb <= pnextf;
  end

  assign qtop = (thru ? dthru : mem[addra]);
  assign qnext = mem[addrb];

endmodule

最終更新時間:2008年05月13日 10時15分29秒