summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usrp2/extramfifo/fifo_extram.v188
-rw-r--r--usrp2/extramfifo/fifo_extram36.v47
-rw-r--r--usrp2/extramfifo/fifo_extram36_tb.build1
-rw-r--r--usrp2/extramfifo/fifo_extram36_tb.v475
-rw-r--r--usrp2/extramfifo/fifo_extram_tb.build1
-rw-r--r--usrp2/extramfifo/fifo_extram_tb.v134
-rw-r--r--usrp2/fifo/fifo18_to_fifo36.v20
-rw-r--r--usrp2/fifo/fifo_2clock_cascade.v14
8 files changed, 876 insertions, 4 deletions
diff --git a/usrp2/extramfifo/fifo_extram.v b/usrp2/extramfifo/fifo_extram.v
new file mode 100644
index 000000000..4e1f40371
--- /dev/null
+++ b/usrp2/extramfifo/fifo_extram.v
@@ -0,0 +1,188 @@
+
+// Everything on sram_clk
+
+module fifo_extram
+ (input reset, input clear,
+ input [17:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space, input [15:0] occ_in,
+ output [17:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied, input [15:0] space_in,
+ input sram_clk, output [18:0] sram_a, inout [17:0] sram_d, output sram_we,
+ output [1:0] sram_bw, output sram_adv, output sram_ce, output sram_oe,
+ output sram_mode, output sram_zz);
+
+ localparam AWIDTH = 19; // 1 MB in x18
+ localparam RAMSIZE = ((1<<AWIDTH) - 1);
+
+ wire do_store, do_retrieve;
+ reg [1:0] do_store_del, do_retr_del;
+
+ reg [AWIDTH-1:0] addr_retrieve, addr_store;
+ always @(posedge sram_clk)
+ if(reset | clear)
+ addr_retrieve <= 0;
+ else if (do_retrieve)
+ addr_retrieve <= addr_retrieve + 1;
+
+ always @(posedge sram_clk)
+ if(reset | clear)
+ addr_store <= 0;
+ else if(do_store)
+ addr_store <= addr_store + 1;
+
+ //wire [AWIDTH-1:0] fullness = (addr_store - addr_retrieve);
+ reg [AWIDTH-1:0] fullness;
+ always @(posedge sram_clk)
+ if(reset | clear)
+ fullness <= 0;
+ else if(do_store)
+ fullness <= fullness + 1;
+ else if(do_retrieve)
+ fullness <= fullness - 1;
+
+ // wire empty = (fullness == 0);
+ //wire full = (fullness == RAMSIZE); // 19'h7FF);
+ reg empty, full;
+
+ // The math in the following functions is 'AWIDTH wide. Use
+ // continuous assignments to prevent the numbers from being
+ // promoted to 32-bit (which would make it wrap wrong).
+ //
+ wire [AWIDTH-1:0] addr_retrieve_p1, addr_store_p2;
+ assign addr_retrieve_p1 = addr_retrieve + 1;
+ assign addr_store_p2 = addr_store + 2;
+
+ always @(posedge sram_clk)
+ if(reset | clear)
+ empty <= 1;
+ else if(do_store)
+ empty <= 0;
+ else if(do_retrieve & (/*(addr_retrieve + 1)*/ addr_retrieve_p1 == addr_store))
+ empty <= 1;
+
+ always @(posedge sram_clk)
+ if(reset | clear)
+ full <= 0;
+ else if(do_retrieve)
+ full <= 0;
+ else if(do_store & (/*(addr_store+2)*/ addr_store_p2 == addr_retrieve))
+ full <= 1;
+
+ reg can_store;
+ always @*
+ if(full | ~src_rdy_i)
+ can_store <= 0;
+ else if(do_store_del == 0)
+ can_store <= 1;
+ else if((do_store_del == 1) || (do_store_del == 2))
+ can_store <= (occ_in > 1);
+ else
+ can_store <= (occ_in > 2);
+
+ reg can_retrieve;
+ always @*
+ if(empty | ~dst_rdy_i)
+ can_retrieve <= 0;
+ else if(do_retr_del == 0)
+ can_retrieve <= 1;
+ else if((do_retr_del == 1) || (do_retr_del == 2))
+ can_retrieve <= (space_in > 1);
+ else
+ can_retrieve <= (space_in > 2);
+
+ reg [1:0] state;
+ localparam IDLE_STORE_NEXT = 0;
+ localparam STORE = 1;
+ localparam IDLE_RETR_NEXT = 2;
+ localparam RETRIEVE = 3;
+
+ reg [7:0] countdown;
+ wire countdown_done = (countdown == 0);
+
+ localparam CYCLE_SIZE = 6;
+
+ assign do_store = can_store & (state == STORE);
+ assign do_retrieve = can_retrieve & (state == RETRIEVE);
+ always @(posedge sram_clk)
+ if(reset)
+ do_store_del <= 0;
+ else
+ do_store_del <= {do_store_del[0],do_store};
+
+ always @(posedge sram_clk)
+ if(reset)
+ do_retr_del <= 0;
+ else
+ do_retr_del <= {do_retr_del[0],do_retrieve};
+
+ always @(posedge sram_clk)
+ if(reset | clear)
+ begin
+ state <= IDLE_STORE_NEXT;
+ countdown <= 0;
+ end
+ else
+ case(state)
+ IDLE_STORE_NEXT :
+ if(can_store)
+ begin
+ state <= STORE;
+ countdown <= CYCLE_SIZE;
+ end
+ else if(can_retrieve)
+ begin
+ state <= RETRIEVE;
+ countdown <= CYCLE_SIZE;
+ end
+ STORE :
+ if(~can_store | (can_retrieve & countdown_done))
+ state <= IDLE_RETR_NEXT;
+ else if(~countdown_done)
+ countdown <= countdown - 1;
+ IDLE_RETR_NEXT :
+ if(can_retrieve)
+ begin
+ state <= RETRIEVE;
+ countdown <= CYCLE_SIZE;
+ end
+ else if(can_store)
+ begin
+ state <= STORE;
+ countdown <= CYCLE_SIZE;
+ end
+ RETRIEVE :
+ if(~can_retrieve | (can_store & countdown_done))
+ state <= IDLE_STORE_NEXT;
+ else if(~countdown_done)
+ countdown <= countdown - 1;
+ endcase // case (state)
+
+ // RAM wires
+ assign sram_bw = 0;
+ assign sram_adv = 0;
+ assign sram_mode = 0;
+ assign sram_zz = 0;
+ assign sram_ce = 0;
+
+ assign sram_a = (state==STORE) ? addr_store : addr_retrieve;
+ assign sram_we = ~do_store;
+ assign sram_oe = ~do_retr_del[1];
+ assign my_oe = do_store_del[1] & sram_oe;
+ assign sram_d = my_oe ? datain : 18'bz;
+
+ // FIFO wires
+ assign dataout = sram_d;
+ assign src_rdy_o = do_retr_del[1];
+ assign dst_rdy_o = do_store_del[1];
+
+endmodule // fifo_extram
+
+
+ //wire have_1 = (fullness == 1);
+ //wire have_2 = (fullness == 2);
+ //wire have_atleast_1 = ~empty;
+ //wire have_atleast_2 = ~(empty | have_1);
+ //wire have_atleast_3 = ~(empty | have_1 | have_2);
+ //wire full_minus_1 = (fullness == (RAMSIZE-1)); // 19'h7FE);
+ //wire full_minus_2 = (fullness == (RAMSIZE-2)); // 19'h7FD);
+ //wire spacefor_atleast_1 = ~full;
+ //wire spacefor_atleast_2 = ~(full | full_minus_1);
+ //wire spacefor_atleast_3 = ~(full | full_minus_1 | full_minus_2);
diff --git a/usrp2/extramfifo/fifo_extram36.v b/usrp2/extramfifo/fifo_extram36.v
new file mode 100644
index 000000000..29342fdc4
--- /dev/null
+++ b/usrp2/extramfifo/fifo_extram36.v
@@ -0,0 +1,47 @@
+
+// 18 bit interface means we either can't handle errors or can't handle odd lengths
+// unless we go to heroic measures
+
+module fifo_extram36
+ (input clk, input reset, input clear,
+ input [35:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space,
+ output [35:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied,
+ input sram_clk, output [18:0] sram_a, inout [17:0] sram_d, output sram_we,
+ output [1:0] sram_bw, output sram_adv, output sram_ce, output sram_oe, output sram_mode,
+ output sram_zz);
+
+ wire [17:0] f18_data_1, f18_data_2, f18_data_3, f18_data_4;
+ wire f18_src_rdy_1, f18_dst_rdy_1, f18_src_rdy_2, f18_dst_rdy_2;
+ wire f18_src_rdy_3, f18_dst_rdy_3, f18_src_rdy_4, f18_dst_rdy_4;
+
+ fifo36_to_fifo18 f36_to_f18
+ (.clk(clk), .reset(reset), .clear(clear),
+ .f36_datain(datain), .f36_src_rdy_i(src_rdy_i), .f36_dst_rdy_o(dst_rdy_o),
+ .f18_dataout(f18_data_1), .f18_src_rdy_o(f18_src_rdy_1), .f18_dst_rdy_i(f18_dst_rdy_1) );
+
+ wire [15:0] f1_occ, f2_space;
+
+ fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) fifo_2clock_in
+ (.wclk(clk), .datain(f18_data_1), .src_rdy_i(f18_src_rdy_1), .dst_rdy_o(f18_dst_rdy_1), .space(),
+ .rclk(sram_clk), .dataout(f18_data_2), .src_rdy_o(f18_src_rdy_2), .dst_rdy_i(f18_dst_rdy_2), .short_occupied(f1_occ),
+ .arst(reset) );
+
+ fifo_extram fifo_extram
+ (.reset(reset), .clear(clear),
+ .datain(f18_data_2), .src_rdy_i(f18_src_rdy_2), .dst_rdy_o(f18_dst_rdy_2), .space(), .occ_in(f1_occ),
+ .dataout(f18_data_3), .src_rdy_o(f18_src_rdy_3), .dst_rdy_i(f18_dst_rdy_3), .occupied(), .space_in(f2_space),
+ .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we),
+ .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe),
+ .sram_mode(sram_mode), .sram_zz(sram_zz));
+
+ fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) fifo_2clock_out
+ (.wclk(sram_clk), .datain(f18_data_3), .src_rdy_i(f18_src_rdy_3), .dst_rdy_o(f18_dst_rdy_3), .short_space(f2_space),
+ .rclk(clk), .dataout(f18_data_4), .src_rdy_o(f18_src_rdy_4), .dst_rdy_i(f18_dst_rdy_4), .occupied(),
+ .arst(reset) );
+
+ fifo18_to_fifo36 f18_to_f36
+ (.clk(clk), .reset(reset), .clear(clear),
+ .f18_datain(f18_data_4), .f18_src_rdy_i(f18_src_rdy_4), .f18_dst_rdy_o(f18_dst_rdy_4),
+ .f36_dataout(dataout), .f36_src_rdy_o(src_rdy_o), .f36_dst_rdy_i(dst_rdy_i) );
+
+endmodule // fifo_extram36
diff --git a/usrp2/extramfifo/fifo_extram36_tb.build b/usrp2/extramfifo/fifo_extram36_tb.build
new file mode 100644
index 000000000..699591889
--- /dev/null
+++ b/usrp2/extramfifo/fifo_extram36_tb.build
@@ -0,0 +1 @@
+iverilog -y ../../models -y ../../models/CY7C1356C -y . -y ../../control_lib/ -y ../../coregen -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -o fifo_extram36_tb fifo_extram36_tb.v
diff --git a/usrp2/extramfifo/fifo_extram36_tb.v b/usrp2/extramfifo/fifo_extram36_tb.v
new file mode 100644
index 000000000..f28c35e4f
--- /dev/null
+++ b/usrp2/extramfifo/fifo_extram36_tb.v
@@ -0,0 +1,475 @@
+`timescale 1ns/1ns
+
+module fifo_extram36_tb();
+
+ reg clk = 0;
+ reg sram_clk = 0;
+ reg rst = 1;
+ reg clear = 0;
+
+ reg Verbose = 0; //
+ integer ErrorCount = 0;
+
+ initial #1000 rst = 0;
+// always #125 clk = ~clk;
+ task task_CLK;
+ reg [7:0] ran;
+ begin
+ while (1) begin
+ ran = $random;
+ if (ran[1])
+ #62 clk = ~clk;
+ else
+ #63 clk = !clk;
+ end
+ end
+ endtask // task_CLK
+ initial task_CLK;
+
+// always #100 sram_clk = ~sram_clk;
+ task task_SSRAM_clk;
+ reg [7:0] ran;
+ begin
+ while (1) begin
+ ran = $random;
+ if (ran[0])
+ #49 sram_clk = ~sram_clk;
+ else
+ #51 sram_clk = ~sram_clk;
+ end
+ end
+ endtask // task_SSRAM_clk
+ initial task_SSRAM_clk;
+
+ reg [31:0] f36_data = 32'hX;
+ reg [1:0] f36_occ = 0;
+ reg f36_sof = 0, f36_eof = 0;
+
+ wire [35:0] f36_in = {1'b0,f36_occ,f36_eof,f36_sof,f36_data};
+ reg src_rdy_f36i = 0;
+ wire dst_rdy_f36i;
+
+ wire [35:0] f36_out;
+ wire src_rdy_f36o;
+ reg dst_rdy_f36o = 0;
+
+ wire [17:0] sram_d;
+ wire [18:0] sram_a;
+ wire [1:0] sram_bw;
+ wire sram_we, sram_adv, sram_ce, sram_oe, sram_mode, sram_zz;
+
+ reg [31:0] ScoreBoard [524288:0];
+ reg [18:0] put_index = 0;
+ reg [18:0] get_index = 0;
+
+// integer put_index = 0;
+// integer get_index = 0;
+
+ wire [15:0] DUT_space, DUT_occupied;
+
+ fifo_extram36 fifo_extram36
+ (.clk(clk), .reset(rst), .clear(clear),
+ .datain(f36_in), .src_rdy_i(src_rdy_f36i), .dst_rdy_o(dst_rdy_f36i), .space(DUT_space),
+ .dataout(f36_out), .src_rdy_o(src_rdy_f36o), .dst_rdy_i(dst_rdy_f36o), .occupied(DUT_occupied),
+ .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we),
+ .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe),
+ .sram_mode(sram_mode), .sram_zz(sram_zz));
+
+`define idt 1
+`ifdef idt
+ wire [15:0] dummy16;
+ wire [1:0] dummy2;
+
+ idt71v65603s150
+ ram_model(.A(sram_a[17:0]),
+ .adv_ld_(sram_adv), // advance (high) / load (low)
+ .bw1_(0), .bw2_(0), .bw3_(0), .bw4_(0), // byte write enables (low)
+ .ce1_(0), .ce2(1), .ce2_(0), // chip enables
+ .cen_(sram_ce), // clock enable (low)
+ .clk(sram_clk), // clock
+ .IO({dummy16,sram_d[15:0]}),
+ .IOP({dummy2,sram_d[17:16]}), // data bus
+ .lbo_(sram_mode), // linear burst order (low)
+ .oe_(sram_oe), // output enable (low)
+ .r_w_(sram_we)); // read (high) / write (low)
+`else
+ cy1356 ram_model(.d(sram_d),.clk(~sram_clk),.a(sram_a),
+ .bws(2'b00),.we_b(sram_we),.adv_lb(sram_adv),
+ .ce1b(0),.ce2(1),.ce3b(0),
+ .oeb(sram_oe),.cenb(sram_ce),.mode(sram_mode) );
+`endif
+
+ task task_SSRAMMonitor;
+ reg last_mode;
+ reg last_clock;
+ reg last_load;
+ reg [18:0] sram_addr;
+
+ begin
+ last_mode = 1'bX;
+ last_clock = 1'bX;
+ last_load = 1'bX;
+
+ @ (posedge Verbose);
+ $dumpvars(0,fifo_extram36_tb);
+
+ $display("%t:%m\t*** Task Started",$time);
+ while (1) @ (posedge sram_clk) begin
+ if (sram_mode !== last_mode) begin
+ $display("%t:%m\tSSRAM mode: %b",$time,sram_mode);
+ last_mode = sram_mode;
+ end
+ if (sram_adv !== last_load) begin
+ $display("%t:%m\tSSRAM adv/load: %b",$time,sram_adv);
+ last_load = sram_adv;
+ end
+ if (sram_ce !== last_clock) begin
+ $display("%t:%m\tSSRAM clock enable: %b",$time,sram_ce);
+ last_clock = sram_ce;
+ end
+ if (sram_ce == 1'b0) begin
+ if (sram_adv == 1'b0) begin
+// $display("%t:%m\tSSRAM Address Load A=%h",$time,sram_a);
+ sram_addr = sram_a;
+ end else begin
+ sram_addr = sram_addr + 1;
+ end
+ if (sram_oe == 1'b0) begin
+ $display("%t:%m\tSSRAM Read Cycle A=%h(%h), D=%o",$time,sram_addr-2,sram_a,sram_d);
+ end
+ if (sram_we == 1'b0) begin
+ $display("%t:%m\tSSRAM Write Cycle A=%h(%h), D=%o",$time,sram_addr-2,sram_a,sram_d);
+ end
+ if ((sram_we == 1'b0) && (sram_oe == 1'b0)) begin
+ $display("%t:%m\t*** ERROR: _oe and _we both active",$time);
+ end
+
+ end // if (sram_ce == 1'b0)
+
+ end // always @ (posedge sram_clk)
+ end
+ endtask // task_SSRAMMonitor
+
+ task ReadFromFIFO36;
+ begin
+ $display("%t: Read from FIFO36",$time);
+ #1 dst_rdy_f36o <= 1;
+ while(1)
+ begin
+ while(~src_rdy_f36o)
+ @(posedge clk);
+ $display("%t: Read: %h>",$time,f36_out);
+ @(posedge clk);
+ end
+ end
+ endtask // ReadFromFIFO36
+
+ initial dst_rdy_f36o = 0;
+
+ task task_ReadFIFO36;
+ reg [7:0] ran;
+ begin
+ $display("%t:%m\t*** Task Started",$time);
+ while (1) begin
+ // Read on one of four clocks
+ #5 dst_rdy_f36o <= 1;
+ @(posedge clk);
+ if (src_rdy_f36o) begin
+ if (f36_out[31:0] != ScoreBoard[get_index]) begin
+ $display("%t:%m\tFIFO Get Error: R:%h, E:%h (%h)",$time,f36_out[31:0],ScoreBoard[get_index],get_index);
+ ErrorCount = ErrorCount + 1;
+ end else begin
+ if (Verbose)
+ $display("%t:%m\t(%5h) %o>",$time,get_index,f36_out);
+ end
+ get_index = get_index+1;
+ end else begin
+ if (ErrorCount >= 192)
+ $finish;
+ end // else: !if(src_rdy_f36o)
+
+ #10;
+ ran = $random;
+ if (ran[2:0] != 3'b000) begin
+ dst_rdy_f36o <= 0;
+ if (ran[2] != 1'b0) begin
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ end
+ if (ran[1] != 1'b0) begin
+ @(posedge clk);
+ @(posedge clk);
+ end
+ if (ran[0] != 1'b0) begin
+ @(posedge clk);
+ end
+ end
+ end // while (1)
+ end
+
+ endtask // task_ReadFIFO36
+
+
+ reg [15:0] count;
+
+ task PutPacketInFIFO36;
+ input [31:0] data_start;
+ input [31:0] data_len;
+
+ begin
+ count = 4;
+ src_rdy_f36i = 1;
+ f36_data = data_start;
+ f36_sof = 1;
+ f36_eof = 0;
+ f36_occ = 0;
+
+ $display("%t: Put Packet in FIFO36",$time);
+ while(~dst_rdy_f36i)
+ #1; //@(posedge clk);
+ @(posedge clk);
+
+ $display("%t: <%h PPI_FIFO36: Entered First Line",$time,f36_data);
+ f36_sof <= 0;
+ while(count+4 < data_len)
+ begin
+ f36_data = f36_data + 32'h01010101;
+ count = count + 4;
+ while(~dst_rdy_f36i)
+ #1; //@(posedge clk);
+ @(posedge clk);
+ $display("%t: <%h PPI_FIFO36: Entered New Line",$time,f36_data);
+ end
+ f36_data <= f36_data + 32'h01010101;
+ f36_eof <= 1;
+ if(count + 4 == data_len)
+ f36_occ <= 0;
+ else if(count + 3 == data_len)
+ f36_occ <= 3;
+ else if(count + 2 == data_len)
+ f36_occ <= 2;
+ else
+ f36_occ <= 1;
+ while(~dst_rdy_f36i)
+ @(posedge clk);
+ @(posedge clk);
+ f36_occ <= 0;
+ f36_eof <= 0;
+ f36_data <= 0;
+ src_rdy_f36i <= 0;
+ $display("%t: <%h PPI_FIFO36: Entered Last Line",$time,f36_data);
+ end
+ endtask // PutPacketInFIFO36
+
+ task task_WriteFIFO36;
+ integer i;
+ reg [7:0] ran;
+
+ begin
+ f36_data = 32'bX;
+ if (rst != 1'b0)
+ @ (negedge rst);
+ $display("%t:%m\t*** Task Started",$time);
+ #10;
+ src_rdy_f36i = 1;
+ f36_data = $random;
+ for (i=0; i<64; i=i+0 ) begin
+ @ (posedge clk) ;
+ if (dst_rdy_f36i) begin
+ if (Verbose)
+ $display("%t:%m\t(%5h) %o<",$time,put_index,f36_in);
+ ScoreBoard[put_index] = f36_in[31:0];
+ put_index = put_index + 1;
+ #5;
+ f36_data = $random;
+ i = i + 1;
+ end
+ ran = $random;
+ if (ran[1:0] != 2'b00) begin
+ @ (negedge clk);
+ src_rdy_f36i = 0;
+ #5;
+ @ (negedge clk) ;
+ src_rdy_f36i = 1;
+ end
+ end
+ src_rdy_f36i = 0;
+ f36_data = 32'bX;
+//* if (put_index > 19'h3ff00)
+//* Verbose = 1'b1;
+
+ end
+ endtask // task_WriteFIFO36
+
+ initial $dumpfile("fifo_extram36_tb.vcd");
+// initial $dumpvars(0,fifo_extram36_tb);
+ initial $timeformat(-9, 0, " ns", 10);
+ initial task_SSRAMMonitor;
+
+ initial
+ begin
+ @(negedge rst);
+ #40000;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+// ReadFromFIFO36;
+ task_ReadFIFO36;
+
+ end
+
+ integer i;
+
+ initial
+ begin
+ @(negedge rst);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ task_WriteFIFO36;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+// PutPacketInFIFO36(32'hA0B0C0D0,12);
+ @(posedge clk);
+ @(posedge clk);
+ #10000;
+ @(posedge clk);
+// PutPacketInFIFO36(32'hE0F0A0B0,36);
+ @(posedge clk);
+ @(posedge clk);
+ task_WriteFIFO36;
+ @(posedge clk);
+ @(posedge clk);
+ #10000;
+ @(posedge clk);
+ @(posedge clk);
+ task_WriteFIFO36;
+// @(posedge clk);
+// #30000;
+// @(posedge clk);
+// @(posedge clk);
+ task_WriteFIFO36;
+// @(posedge clk);
+// #30000;
+// @(posedge clk);
+// @(posedge clk);
+ task_WriteFIFO36;
+// @(posedge clk);
+// #30000;
+// @(posedge clk);
+// @(posedge clk);
+ task_WriteFIFO36;
+ @(posedge clk);
+ #10000;
+ @(posedge clk);
+ @(posedge clk);
+ task_WriteFIFO36;
+ for (i=0; i<8192; i = i+1) begin
+ @(posedge clk);
+ #10000;
+ @(posedge clk);
+ @(posedge clk);
+ task_WriteFIFO36;
+ @(posedge clk);
+ end
+
+// $dumpvars(0,fifo_extram36_tb);
+ @(posedge clk);
+ task_WriteFIFO36;
+ @(posedge clk);
+
+ #100000000;
+ $finish;
+
+ end
+ */
+
+ initial
+ begin
+ @(negedge rst);
+ f36_occ <= 0;
+ repeat (100)
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= 32'h10203040;
+ f36_sof <= 1;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= f36_data + 32'h01010101;
+ f36_sof <= 0;
+ f36_eof <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 1;
+ f36_data <= 32'h1F2F3F4F;
+ f36_sof <= 0;
+ f36_eof <= 1;
+ @(posedge clk);
+ @(posedge clk);
+ src_rdy_f36i <= 0;
+
+
+
+ end
+
+// initial #500000 $finish;
+endmodule // fifo_extram_tb
diff --git a/usrp2/extramfifo/fifo_extram_tb.build b/usrp2/extramfifo/fifo_extram_tb.build
new file mode 100644
index 000000000..e87217e5c
--- /dev/null
+++ b/usrp2/extramfifo/fifo_extram_tb.build
@@ -0,0 +1 @@
+iverilog -y ../../models -y ../../models/CY7C1356C -y . -y ../../control_lib/ -y ../../coregen -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -o fifo_extram_tb fifo_extram_tb.v
diff --git a/usrp2/extramfifo/fifo_extram_tb.v b/usrp2/extramfifo/fifo_extram_tb.v
new file mode 100644
index 000000000..73550d9ca
--- /dev/null
+++ b/usrp2/extramfifo/fifo_extram_tb.v
@@ -0,0 +1,134 @@
+module fifo_extram_tb();
+
+ reg clk = 0;
+ reg sram_clk = 0;
+ reg reset = 1;
+ reg clear = 0;
+
+ initial #1000 reset = 0;
+ always #125 clk = ~clk;
+ always #100 sram_clk = ~sram_clk;
+
+ reg [15:0] f18_data = 0;
+ reg f18_sof = 0, f18_eof = 0;
+
+ wire [17:0] f18_in = {f18_eof,f18_sof,f18_data};
+ reg src_rdy_f18i = 0;
+ wire dst_rdy_f18i;
+
+ wire [17:0] f18_out;
+ wire src_rdy_f18o;
+ reg dst_rdy_f18o = 0;
+
+ wire [17:0] f18_int;
+ wire src_rdy_f18int, dst_rdy_f18int;
+
+ wire [17:0] sram_d;
+ wire [18:0] sram_a;
+ wire [1:0] sram_bw;
+ wire sram_we, sram_adv, sram_ce, sram_oe, sram_mode, sram_zz;
+ wire [15:0] f1_occ;
+
+ fifo_short #(.WIDTH(18)) fifo_short
+ (.clk(sram_clk), .reset(reset), .clear(clear),
+ .datain(f18_in), .src_rdy_i(src_rdy_f18i), .dst_rdy_o(dst_rdy_f18i), .space(),
+ .dataout(f18_int), .src_rdy_o(src_rdy_f18int), .dst_rdy_i(dst_rdy_f18int), .occupied(f1_occ[4:0]) );
+
+ assign f1_occ[15:5] = 0;
+
+ fifo_extram fifo_extram
+ (.reset(reset), .clear(clear),
+ .datain(f18_int), .src_rdy_i(src_rdy_f18int), .dst_rdy_o(dst_rdy_f18int), .space(), .occ_in(f1_occ),
+ .dataout(f18_out), .src_rdy_o(src_rdy_f18o), .dst_rdy_i(dst_rdy_f18o), .occupied(), .space_in(7),
+ .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we),
+ .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe),
+ .sram_mode(sram_mode), .sram_zz(sram_zz));
+
+`define idt 1
+`ifdef idt
+ wire [15:0] dummy16;
+ wire [1:0] dummy2;
+
+ idt71v65603s150
+ ram_model(.A(sram_a[17:0]),
+ .adv_ld_(sram_adv), // advance (high) / load (low)
+ .bw1_(0), .bw2_(0), .bw3_(0), .bw4_(0), // byte write enables (low)
+ .ce1_(0), .ce2(1), .ce2_(0), // chip enables
+ .cen_(sram_ce), // clock enable (low)
+ .clk(sram_clk), // clock
+ .IO({dummy16,sram_d[15:0]}),
+ .IOP({dummy2,sram_d[17:16]}), // data bus
+ .lbo_(sram_mode), // linear burst order (low)
+ .oe_(sram_oe), // output enable (low)
+ .r_w_(sram_we)); // read (high) / write (low)
+`else
+ cy1356 ram_model(.d(sram_d),.clk(sram_clk),.a(sram_a),
+ .bws(2'b00),.we_b(sram_we),.adv_lb(sram_adv),
+ .ce1b(0),.ce2(1),.ce3b(0),
+ .oeb(sram_oe),.cenb(sram_ce),.mode(sram_mode) );
+`endif // !`ifdef idt
+
+ always @(posedge sram_clk)
+ if(dst_rdy_f18o & src_rdy_f18o)
+ $display("Read: %h",f18_out);
+
+ always @(posedge sram_clk)
+ if(dst_rdy_f18int & src_rdy_f18int)
+ $display("Write: %h",f18_int);
+
+ initial $dumpfile("fifo_extram_tb.vcd");
+ initial $dumpvars(0,fifo_extram_tb);
+
+ task SendPkt;
+ input [15:0] data_start;
+ input [31:0] data_len;
+ begin
+ @(posedge sram_clk);
+ f18_data = data_start;
+ f18_sof = 1;
+ f18_eof = 0;
+ src_rdy_f18i = 1;
+ while(~dst_rdy_f18i)
+ #1;
+ @(posedge sram_clk);
+ repeat(data_len - 2)
+ begin
+ f18_data = f18_data + 16'h0101;
+ f18_sof = 0;
+ while(~dst_rdy_f18i)
+ @(posedge sram_clk);
+
+ @(posedge sram_clk);
+ end
+ f18_data = f18_data + 16'h0101;
+ f18_eof = 1;
+ while(~dst_rdy_f18i)
+ #1;
+ @(posedge sram_clk);
+ src_rdy_f18i = 0;
+ f18_data = 0;
+ f18_eof = 0;
+ end
+ endtask // SendPkt
+
+ initial
+ begin
+ @(negedge reset);
+ @(posedge sram_clk);
+ @(posedge sram_clk);
+ #10000;
+ @(posedge sram_clk);
+ SendPkt(16'hA0B0, 100);
+ #10000;
+ //SendPkt(16'hC0D0, 220);
+ end
+
+ initial
+ begin
+ #20000;
+ dst_rdy_f18o = 1;
+ end
+
+ initial #200000 $finish;
+endmodule // fifo_extram_tb
+
diff --git a/usrp2/fifo/fifo18_to_fifo36.v b/usrp2/fifo/fifo18_to_fifo36.v
new file mode 100644
index 000000000..25bb215a1
--- /dev/null
+++ b/usrp2/fifo/fifo18_to_fifo36.v
@@ -0,0 +1,20 @@
+
+// For now just assume FIFO18 is same as FIFO19 without occupancy bit
+
+module fifo18_to_fifo36
+ (input clk, input reset, input clear,
+ input [17:0] f18_datain,
+ input f18_src_rdy_i,
+ output f18_dst_rdy_o,
+
+ output [35:0] f36_dataout,
+ output f36_src_rdy_o,
+ input f36_dst_rdy_i
+ );
+
+ fifo19_to_fifo36 fifo19_to_fifo36
+ (.clk(clk), .reset(reset), .clear(clear),
+ .f19_datain({1'b0,f18_datain}), .f19_src_rdy_i(f18_src_rdy_i), .f19_dst_rdy_o(f18_dst_rdy_o),
+ .f36_dataout(f36_dataout), .f36_src_rdy_o(f36_src_rdy_o), .f36_dst_rdy_i(f36_dst_rdy_i) );
+
+endmodule // fifo18_to_fifo36
diff --git a/usrp2/fifo/fifo_2clock_cascade.v b/usrp2/fifo/fifo_2clock_cascade.v
index 5ce726977..4e8c244c2 100644
--- a/usrp2/fifo/fifo_2clock_cascade.v
+++ b/usrp2/fifo/fifo_2clock_cascade.v
@@ -1,8 +1,10 @@
module fifo_2clock_cascade
#(parameter WIDTH=32, SIZE=9)
- (input wclk, input [WIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space,
- input rclk, output [WIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied,
+ (input wclk, input [WIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o,
+ output [15:0] space, output [15:0] short_space,
+ input rclk, output [WIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i,
+ output [15:0] occupied, output [15:0] short_occupied,
input arst);
wire [WIDTH-1:0] data_int1, data_int2;
@@ -29,7 +31,11 @@ module fifo_2clock_cascade
.space(s2_space), .occupied(s2_occupied));
// Be conservative -- Only advertise space from input side of fifo, occupied from output side
- assign space = {11'b0,s1_space} + l_space;
- assign occupied = {11'b0,s2_occupied} + l_occupied;
+ assign space = {11'b0,s1_space} + l_space;
+ assign occupied = {11'b0,s2_occupied} + l_occupied;
+
+ // For the fifo_extram, we only want to know the immediately adjacent space
+ assign short_space = {11'b0,s1_space};
+ assign short_occupied = {11'b0,s2_occupied};
endmodule // fifo_2clock_cascade