diff options
-rw-r--r-- | usrp2/extramfifo/fifo_extram.v | 188 | ||||
-rw-r--r-- | usrp2/extramfifo/fifo_extram36.v | 47 | ||||
-rw-r--r-- | usrp2/extramfifo/fifo_extram36_tb.build | 1 | ||||
-rw-r--r-- | usrp2/extramfifo/fifo_extram36_tb.v | 475 | ||||
-rw-r--r-- | usrp2/extramfifo/fifo_extram_tb.build | 1 | ||||
-rw-r--r-- | usrp2/extramfifo/fifo_extram_tb.v | 134 | ||||
-rw-r--r-- | usrp2/fifo/fifo18_to_fifo36.v | 20 | ||||
-rw-r--r-- | usrp2/fifo/fifo_2clock_cascade.v | 14 |
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 |