2017-01-06 1 views
1

私はiCE40HX-8KブレークアウトボードでブロックRAMを使用する方法を理解しようとしています。私は512x8の設定でアクセスしたいと思いますが、ドキュメンテーションからわかるように、プロジェクトIceStormでサポートされていますが、期待通りに動作させることができませんでした。IceStormで512x8読み取りモードでiCE40 4KブロックRAMを使用するにはどうすればよいですか?

私が正しく理解している場合、READ_MODEパラメータを1に設定してSB_RAM40_4Kプリミティブを初期化すると、ブロックを512x8リードモードに設定する必要があります。これは9ビットのリードアドレスを使用し、各アドレスで8ビットのデータを読み込みます。ここで

は、私は考えることができ、最も簡単な例です。これは、事前に初期化されたメモリを備えたSB_RAM40_4Kを設定し、オンボードLEDのピンにまっすぐに読み取ります。

hx8kboard.pcf

set_io leds[0] B5 
set_io leds[1] B4 
set_io leds[2] A2 
set_io leds[3] A1 
set_io leds[4] C5 
set_io leds[5] C4 
set_io leds[6] B3 
set_io leds[7] C3 
set_io clk J3 

top.v

module top (
    output [7:0] leds, 
    input clk 
); 

//reg [8:0] raddr = 8'd0; 
reg [8:0] raddr = 8'd1; 

SB_RAM40_4K #(
    .INIT_0(256'h00000000000000000000000000000000000000000000000000000000_44_33_22_11), 
    .WRITE_MODE(1), 
    .READ_MODE(1) 
) ram40_4k_512x8 (
    .RDATA(leds), 
    .RADDR(raddr), 
    .RCLK(clk), 
    .RCLKE(1'b1), 
    .RE(1'b1), 
    .WADDR(8'b0), 
    .WCLK(1'b0), 
    .WCLKE(1'b0), 
    .WDATA(8'b0), 
    .WE(1'b0) 
); 

endmodule 
RADDR == 0

  \|/    \|/ 
O O O O O O O O 

出力RADDR == 1

 \|/ \|/   \|/ \|/ 
O O O O O O O O 
のLED

LED出力

Iは512x8モードにおけるアドレス1は8'h22又は8'b0010010あるRAMから第8ビットであろうと思うだろう。代わりに8'h33または8'b00110011が得られます。ちょっと試してみると、これは16ビットの読み込みの下位8ビットのようです。

どこが間違っているのか分かりません。ここで何が起こっているのかを理解する助けがあれば歓迎されます。ありがとう!

答えて

2

この質問はYosysまたはプロジェクトアイス・ストームについては本当にありません。 SB_RAM40_4KINIT_*パラメータに使用されるフォーマットは、IceStormフローとLattice iCEcube2フローで同じです。しかし、Latticeはこの形式を文書化するのに非常に悪い仕事をしています。そうでなければ私はちょうど、ラティスの文書にあなたを指すと思います。.. :)

あなたは512x8モードに興味を持っています。まず、512x8モードでは、.RDATA().WDATA()の偶数ビットのみが使用されていることを確認する必要があります(コードが示すように、8LSBビットではありません)。

.INIT_*のデータは、パラメータごとに16個の16ビットワードとして格納されます。 .INIT_0()の最下位の16ビットワードは、偶数ビットのaddr 0の8ビットワードと、奇数ビットのaddr 256の8ビットワードとを含む。

.INIT_0()の次の16ビットワードには、ワード1と257が含まれます。.INIT_1()の最下位16ビットには、ワード16と272などが含まれています。

この種のものを調べる最も簡単な方法は、シミュレーションモデル/usr/local/share/yosys/ice40/cells_sim.vを読んだり、Yosysにメモリを推測させて、yosysの動作を観察させることです。たとえば、次のような設計:yosys -p 'synth_ice40; write_verilog' test.vを介して実行時に

module test(input clk, wen, input [8:0] addr, input [7:0] wdata, output reg [7:0] rdata); 
    reg [7:0] mem [0:511]; 
    initial mem[0] = 255; 
    always @(posedge clk) begin 
     if (wen) mem[addr] <= wdata; 
     rdata <= mem[addr]; 
    end 
endmodule 

は、次のような出力を生成します:

(* top = 1 *) 
(* src = "test.v:1" *) 
module test(clk, wen, addr, wdata, rdata); 
    (* src = "/usr/local/bin/../share/yosys/ice40/brams_map.v:255" *) 
    (* unused_bits = "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" *) 
    wire [15:0] _0_; 
    (* src = "test.v:1" *) 
    input [8:0] addr; 
    (* src = "test.v:1" *) 
    input clk; 
    (* src = "test.v:1" *) 
    output [7:0] rdata; 
    (* src = "test.v:1" *) 
    input [7:0] wdata; 
    (* src = "test.v:1" *) 
    input wen; 
    (* src = "/usr/local/bin/../share/yosys/ice40/brams_map.v:277|/usr/local/bin/../share/yosys/ice40/brams_map.v:35" *) 
    SB_RAM40_4K #(
    .INIT_0(256'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1x1x1x1x1x1x1x1), 
    .INIT_1(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_2(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_3(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_4(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_5(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_6(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_7(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_8(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_9(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_A(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_B(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_C(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_D(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_E(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .INIT_F(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), 
    .READ_MODE(32'sd1), 
    .WRITE_MODE(32'sd1) 
) \mem.0.0.0 (
    .MASK(16'hxxxx), 
    .RADDR({ 2'h0, addr }), 
    .RCLK(clk), 
    .RCLKE(1'h1), 
    .RDATA({ _0_[15], rdata[7], _0_[13], rdata[6], _0_[11], rdata[5], _0_[9], rdata[4], _0_[7], rdata[3], _0_[5], rdata[2], _0_[3], rdata[1], _0_[1], rdata[0] }), 
    .RE(1'h1), 
    .WADDR({ 2'h0, addr }), 
    .WCLK(clk), 
    .WCLKE(wen), 
    .WDATA({ 1'hx, wdata[7], 1'hx, wdata[6], 1'hx, wdata[5], 1'hx, wdata[4], 1'hx, wdata[3], 1'hx, wdata[2], 1'hx, wdata[1], 1'hx, wdata[0] }), 
    .WE(1'h1) 
); 
endmodule 

を(すべての道mem[0] = 255初期化のために生成された初期化パターンを参照するには右にスクロールします。)

+1

詳細な説明をありがとうございます! –

+0

補間は有効なBRAMモードの1つである8ビットレジスタを使用しているので機能しますか? 32または64、または非電源または2の幅はどうですか?いくつかのアクセスを行うことが推測されるのだろうか、あるいはデータを1クロック・ティックでフェッチできないので、レジスタの規則的な配列(多くのPLBを消費する)として合成されるだろうか? – Piranna

関連する問題