aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp2/control_lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-04-15 11:24:24 -0700
committerJosh Blum <josh@joshknows.com>2010-04-15 11:24:24 -0700
commit05d77f772317de5d925301aa11bb9a880656dd05 (patch)
tree0910bfb9265fab1644a3d3a1706719f1b038d193 /fpga/usrp2/control_lib
parent16818dc98e97b69a028c47e66ebfb16e32565533 (diff)
downloaduhd-05d77f772317de5d925301aa11bb9a880656dd05.tar.gz
uhd-05d77f772317de5d925301aa11bb9a880656dd05.tar.bz2
uhd-05d77f772317de5d925301aa11bb9a880656dd05.zip
moved usrp1 and usrp2 fpga dirs into fpga subdirectory
Diffstat (limited to 'fpga/usrp2/control_lib')
-rw-r--r--fpga/usrp2/control_lib/.gitignore5
-rw-r--r--fpga/usrp2/control_lib/CRC16_D16.v89
-rw-r--r--fpga/usrp2/control_lib/atr_controller.v57
-rw-r--r--fpga/usrp2/control_lib/bin2gray.v10
-rw-r--r--fpga/usrp2/control_lib/bootrom.mem26
-rw-r--r--fpga/usrp2/control_lib/clock_bootstrap_rom.v34
-rw-r--r--fpga/usrp2/control_lib/clock_control.v115
-rw-r--r--fpga/usrp2/control_lib/clock_control_tb.v35
-rw-r--r--fpga/usrp2/control_lib/cmdfile18
-rw-r--r--fpga/usrp2/control_lib/dcache.v165
-rw-r--r--fpga/usrp2/control_lib/decoder_3_8.v21
-rw-r--r--fpga/usrp2/control_lib/dpram32.v82
-rw-r--r--fpga/usrp2/control_lib/fifo_tb.v151
-rw-r--r--fpga/usrp2/control_lib/gray2bin.v13
-rw-r--r--fpga/usrp2/control_lib/gray_send.v29
-rw-r--r--fpga/usrp2/control_lib/icache.v135
-rw-r--r--fpga/usrp2/control_lib/longfifo.v150
-rw-r--r--fpga/usrp2/control_lib/medfifo.v49
-rw-r--r--fpga/usrp2/control_lib/mux4.v16
-rw-r--r--fpga/usrp2/control_lib/mux8.v21
-rw-r--r--fpga/usrp2/control_lib/mux_32_4.v13
-rw-r--r--fpga/usrp2/control_lib/newfifo/.gitignore1
-rw-r--r--fpga/usrp2/control_lib/newfifo/buffer_int.v168
-rw-r--r--fpga/usrp2/control_lib/newfifo/buffer_int_tb.v418
-rw-r--r--fpga/usrp2/control_lib/newfifo/buffer_pool.v283
-rw-r--r--fpga/usrp2/control_lib/newfifo/buffer_pool_tb.v58
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo19_to_fifo36.v76
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo19_to_ll8.v53
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo36_to_fifo18.v40
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo36_to_fifo19.v41
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo36_to_ll8.v60
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo_2clock.v117
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo_2clock_cascade.v35
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo_cascade.v52
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo_long.v148
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo_new_tb.vcd5506
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo_short.v95
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo_spec.txt36
-rw-r--r--fpga/usrp2/control_lib/newfifo/fifo_tb.v158
-rw-r--r--fpga/usrp2/control_lib/newfifo/ll8_shortfifo.v13
-rw-r--r--fpga/usrp2/control_lib/newfifo/ll8_to_fifo19.v73
-rw-r--r--fpga/usrp2/control_lib/newfifo/ll8_to_fifo36.v97
-rw-r--r--fpga/usrp2/control_lib/nsgpio.v107
-rw-r--r--fpga/usrp2/control_lib/oneshot_2clk.v35
-rw-r--r--fpga/usrp2/control_lib/pic.v183
-rw-r--r--fpga/usrp2/control_lib/priority_enc.v44
-rw-r--r--fpga/usrp2/control_lib/ram_2port.v42
-rw-r--r--fpga/usrp2/control_lib/ram_harv_cache.v75
-rw-r--r--fpga/usrp2/control_lib/ram_loader.v225
-rw-r--r--fpga/usrp2/control_lib/ram_wb_harvard.v86
-rw-r--r--fpga/usrp2/control_lib/reset_sync.v16
-rw-r--r--fpga/usrp2/control_lib/sd_spi.v70
-rw-r--r--fpga/usrp2/control_lib/sd_spi_tb.v40
-rw-r--r--fpga/usrp2/control_lib/sd_spi_wb.v76
-rw-r--r--fpga/usrp2/control_lib/setting_reg.v23
-rw-r--r--fpga/usrp2/control_lib/settings_bus.v49
-rw-r--r--fpga/usrp2/control_lib/shortfifo.v87
-rw-r--r--fpga/usrp2/control_lib/simple_uart.v61
-rw-r--r--fpga/usrp2/control_lib/simple_uart_rx.v64
-rw-r--r--fpga/usrp2/control_lib/simple_uart_tx.v60
-rw-r--r--fpga/usrp2/control_lib/spi.v84
-rw-r--r--fpga/usrp2/control_lib/srl.v21
-rw-r--r--fpga/usrp2/control_lib/ss_rcvr.v81
-rw-r--r--fpga/usrp2/control_lib/system_control.v47
-rw-r--r--fpga/usrp2/control_lib/system_control_tb.v57
-rw-r--r--fpga/usrp2/control_lib/traffic_cop.v25
-rw-r--r--fpga/usrp2/control_lib/wb_1master.v464
-rw-r--r--fpga/usrp2/control_lib/wb_bridge_16_32.v36
-rw-r--r--fpga/usrp2/control_lib/wb_bus_writer.v57
-rw-r--r--fpga/usrp2/control_lib/wb_output_pins32.v49
-rw-r--r--fpga/usrp2/control_lib/wb_ram_block.v36
-rw-r--r--fpga/usrp2/control_lib/wb_ram_dist.v33
-rw-r--r--fpga/usrp2/control_lib/wb_readback_mux.v60
-rw-r--r--fpga/usrp2/control_lib/wb_regfile_2clock.v107
-rw-r--r--fpga/usrp2/control_lib/wb_semaphore.v42
-rw-r--r--fpga/usrp2/control_lib/wb_sim.v79
76 files changed, 11383 insertions, 0 deletions
diff --git a/fpga/usrp2/control_lib/.gitignore b/fpga/usrp2/control_lib/.gitignore
new file mode 100644
index 000000000..025385cff
--- /dev/null
+++ b/fpga/usrp2/control_lib/.gitignore
@@ -0,0 +1,5 @@
+/a.out
+/*.vcd
+/*.lxt
+/*.sav
+/*.log
diff --git a/fpga/usrp2/control_lib/CRC16_D16.v b/fpga/usrp2/control_lib/CRC16_D16.v
new file mode 100644
index 000000000..7e2816af1
--- /dev/null
+++ b/fpga/usrp2/control_lib/CRC16_D16.v
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////
+// File: CRC16_D16.v
+// Date: Sun Jun 17 06:42:55 2007
+//
+// Copyright (C) 1999-2003 Easics NV.
+// This source file may be used and distributed without restriction
+// provided that this copyright statement is not removed from the file
+// and that any derivative work contains the original copyright notice
+// and the associated disclaimer.
+//
+// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
+// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Purpose: Verilog module containing a synthesizable CRC function
+// * polynomial: (0 5 12 16)
+// * data width: 16
+//
+// Info: tools@easics.be
+// http://www.easics.com
+///////////////////////////////////////////////////////////////////////
+
+
+module CRC16_D16
+ (input [15:0] Data,
+ input [15:0] CRC,
+ output [15:0] NewCRC);
+
+ assign NewCRC = nextCRC16_D16(Data,CRC);
+
+ // polynomial: (0 5 12 16)
+ // data width: 16
+ // convention: the first serial data bit is D[15]
+ function [15:0] nextCRC16_D16;
+
+ input [15:0] Data;
+ input [15:0] CRC;
+
+ reg [15:0] D;
+ reg [15:0] C;
+ reg [15:0] NewCRC;
+
+ begin
+
+ D = Data;
+ C = CRC;
+
+ NewCRC[0] = D[12] ^ D[11] ^ D[8] ^ D[4] ^ D[0] ^ C[0] ^ C[4] ^
+ C[8] ^ C[11] ^ C[12];
+ NewCRC[1] = D[13] ^ D[12] ^ D[9] ^ D[5] ^ D[1] ^ C[1] ^ C[5] ^
+ C[9] ^ C[12] ^ C[13];
+ NewCRC[2] = D[14] ^ D[13] ^ D[10] ^ D[6] ^ D[2] ^ C[2] ^ C[6] ^
+ C[10] ^ C[13] ^ C[14];
+ NewCRC[3] = D[15] ^ D[14] ^ D[11] ^ D[7] ^ D[3] ^ C[3] ^ C[7] ^
+ C[11] ^ C[14] ^ C[15];
+ NewCRC[4] = D[15] ^ D[12] ^ D[8] ^ D[4] ^ C[4] ^ C[8] ^ C[12] ^
+ C[15];
+ NewCRC[5] = D[13] ^ D[12] ^ D[11] ^ D[9] ^ D[8] ^ D[5] ^ D[4] ^
+ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[8] ^ C[9] ^ C[11] ^ C[12] ^
+ C[13];
+ NewCRC[6] = D[14] ^ D[13] ^ D[12] ^ D[10] ^ D[9] ^ D[6] ^ D[5] ^
+ D[1] ^ C[1] ^ C[5] ^ C[6] ^ C[9] ^ C[10] ^ C[12] ^
+ C[13] ^ C[14];
+ NewCRC[7] = D[15] ^ D[14] ^ D[13] ^ D[11] ^ D[10] ^ D[7] ^ D[6] ^
+ D[2] ^ C[2] ^ C[6] ^ C[7] ^ C[10] ^ C[11] ^ C[13] ^
+ C[14] ^ C[15];
+ NewCRC[8] = D[15] ^ D[14] ^ D[12] ^ D[11] ^ D[8] ^ D[7] ^ D[3] ^
+ C[3] ^ C[7] ^ C[8] ^ C[11] ^ C[12] ^ C[14] ^ C[15];
+ NewCRC[9] = D[15] ^ D[13] ^ D[12] ^ D[9] ^ D[8] ^ D[4] ^ C[4] ^
+ C[8] ^ C[9] ^ C[12] ^ C[13] ^ C[15];
+ NewCRC[10] = D[14] ^ D[13] ^ D[10] ^ D[9] ^ D[5] ^ C[5] ^ C[9] ^
+ C[10] ^ C[13] ^ C[14];
+ NewCRC[11] = D[15] ^ D[14] ^ D[11] ^ D[10] ^ D[6] ^ C[6] ^ C[10] ^
+ C[11] ^ C[14] ^ C[15];
+ NewCRC[12] = D[15] ^ D[8] ^ D[7] ^ D[4] ^ D[0] ^ C[0] ^ C[4] ^ C[7] ^
+ C[8] ^ C[15];
+ NewCRC[13] = D[9] ^ D[8] ^ D[5] ^ D[1] ^ C[1] ^ C[5] ^ C[8] ^ C[9];
+ NewCRC[14] = D[10] ^ D[9] ^ D[6] ^ D[2] ^ C[2] ^ C[6] ^ C[9] ^ C[10];
+ NewCRC[15] = D[11] ^ D[10] ^ D[7] ^ D[3] ^ C[3] ^ C[7] ^ C[10] ^
+ C[11];
+
+ nextCRC16_D16 = NewCRC;
+
+ end
+
+ endfunction
+
+endmodule
+
diff --git a/fpga/usrp2/control_lib/atr_controller.v b/fpga/usrp2/control_lib/atr_controller.v
new file mode 100644
index 000000000..fed2791f9
--- /dev/null
+++ b/fpga/usrp2/control_lib/atr_controller.v
@@ -0,0 +1,57 @@
+
+// Automatic transmit/receive switching of control pins to daughterboards
+// Store everything in registers for now, but could use a RAM for more
+// complex state machines in the future
+
+module atr_controller
+ (input clk_i, input rst_i,
+ input [5:0] adr_i, input [3:0] sel_i, input [31:0] dat_i, output reg [31:0] dat_o,
+ input we_i, input stb_i, input cyc_i, output reg ack_o,
+ input run_rx, input run_tx, input [31:0] master_time,
+ output [31:0] ctrl_lines);
+
+ reg [3:0] state;
+ reg [31:0] atr_ram [0:15]; // DP distributed RAM
+
+ // WB Interface
+ always @(posedge clk_i)
+ if(we_i & stb_i & cyc_i)
+ begin
+ if(sel_i[3])
+ atr_ram[adr_i[5:2]][31:24] <= dat_i[31:24];
+ if(sel_i[2])
+ atr_ram[adr_i[5:2]][23:16] <= dat_i[23:16];
+ if(sel_i[1])
+ atr_ram[adr_i[5:2]][15:8] <= dat_i[15:8];
+ if(sel_i[0])
+ atr_ram[adr_i[5:2]][7:0] <= dat_i[7:0];
+ end // if (we_i & stb_i & cyc_i)
+
+ always @(posedge clk_i)
+ dat_o <= atr_ram[adr_i[5:2]];
+
+ always @(posedge clk_i)
+ ack_o <= stb_i & cyc_i & ~ack_o;
+
+ // Control side of DP RAM
+ assign ctrl_lines = atr_ram[state];
+
+ // Put a more complex state machine with time delays and multiple states here
+ // if daughterboard requires more complex sequencing
+ localparam ATR_IDLE = 4'd0;
+ localparam ATR_TX = 4'd1;
+ localparam ATR_RX = 4'd2;
+ localparam ATR_FULL_DUPLEX = 4'd3;
+
+ always @(posedge clk_i)
+ if(rst_i)
+ state <= ATR_IDLE;
+ else
+ case ({run_rx,run_tx})
+ 2'b00 : state <= ATR_IDLE;
+ 2'b01 : state <= ATR_TX;
+ 2'b10 : state <= ATR_RX;
+ 2'b11 : state <= ATR_FULL_DUPLEX;
+ endcase // case({run_rx,run_tx})
+
+endmodule // atr_controller
diff --git a/fpga/usrp2/control_lib/bin2gray.v b/fpga/usrp2/control_lib/bin2gray.v
new file mode 100644
index 000000000..513402163
--- /dev/null
+++ b/fpga/usrp2/control_lib/bin2gray.v
@@ -0,0 +1,10 @@
+
+
+module bin2gray
+ #(parameter WIDTH=8)
+ (input [WIDTH-1:0] bin,
+ output [WIDTH-1:0] gray);
+
+ assign gray = (bin >> 1) ^ bin;
+
+endmodule // bin2gray
diff --git a/fpga/usrp2/control_lib/bootrom.mem b/fpga/usrp2/control_lib/bootrom.mem
new file mode 100644
index 000000000..d688b4342
--- /dev/null
+++ b/fpga/usrp2/control_lib/bootrom.mem
@@ -0,0 +1,26 @@
+00000C000F03
+101400000000
+ // SPI: Set Divider to div by 2
+// Both clk sel choose ext ref (0), both are enabled (1), turn off SERDES, ADCs, turn on leds
+1018_0000_0001 // SPI: Choose AD9510
+1010_0000_3418 // SPI: Auto-slave select, interrupt when done, TX_NEG, 24-bit word
+1000_0000_0010 // SPI: AD9510 A:0 D:10 Set up AD9510 SPI
+1010_0000_3518 // SPI: SEND IT Auto-slave select, interrupt when done, TX_NEG, 24-bit word
+ffff_ffff_ffff // terminate
+#// First 16 bits are address, last 32 are data
+#// First 4 bits of address select which slave
+// 6'd01 : addr_data = {13'h45,8'h00}; // CLK2 drives distribution, everything on
+// 6'd02 : addr_data = {13'h3D,8'h80}; // Turn on output 1, normal levels
+// 6'd03 : addr_data = {13'h4B,8'h80}; // Bypass divider 1 (div by 1)
+// 6'd04 : addr_data = {13'h08,8'h47}; // POS PFD, Dig LK Det, Charge Pump normal
+// 6'd05 : addr_data = {13'h09,8'h70}; // Max Charge Pump current
+// 6'd06 : addr_data = {13'h0A,8'h04}; // Normal operation, Prescalar Div by 2, PLL On
+// 6'd07 : addr_data = {13'h0B,8'h00}; // RDIV MSB (6 bits)
+// 6'd08 : addr_data = {13'h0C,8'h01}; // RDIV LSB (8 bits), Div by 1
+// 6'd09 : addr_data = {13'h0D,8'h00}; // Everything normal, Dig Lock Det
+// 6'd10 : addr_data = {13'h07,8'h00}; // Disable LOR detect - LOR causes failure...
+// 6'd11 : addr_data = {13'h04,8'h00}; // A Counter = Don't Care
+// 6'd12 : addr_data = {13'h05,8'h00}; // B Counter MSB = 0
+// 6'd13 : addr_data = {13'h06,8'h05}; // B Counter LSB = 5
+ // default : addr_data = {13'h5A,8'h01}; // Register Update
+// @ 55 // Jump to new address 8'h55
diff --git a/fpga/usrp2/control_lib/clock_bootstrap_rom.v b/fpga/usrp2/control_lib/clock_bootstrap_rom.v
new file mode 100644
index 000000000..46563db65
--- /dev/null
+++ b/fpga/usrp2/control_lib/clock_bootstrap_rom.v
@@ -0,0 +1,34 @@
+
+
+module clock_bootstrap_rom(input [15:0] addr, output [47:0] data);
+
+ reg [47:0] rom [0:15];
+
+ //initial
+ // $readmemh("bootrom.mem", rom);
+
+ assign data = rom[addr];
+
+ initial
+ begin
+ // First 16 bits are address, last 32 are data
+ // First 4 bits of address select which slave
+ rom[0] = 48'h0000_0C00_0F03; // Both clk sel choose ext ref (0), both are enabled (1), turn off SERDES, ADCs, turn on leds
+ rom[1] = 48'h1014_0000_0000; // SPI: Set Divider to div by 2
+ rom[2] = 48'h1018_0000_0001; // SPI: Choose AD9510
+ rom[3] = 48'h1010_0000_3418; // SPI: Auto-slave select, interrupt when done, TX_NEG, 24-bit word
+ rom[4] = 48'h1000_0000_0010; // SPI: AD9510 A:0 D:10 Set up AD9510 SPI
+ rom[5] = 48'h1010_0000_3518; // SPI: SEND IT Auto-slave select, interrupt when done, TX_NEG, 24-bit word
+ rom[6] = 48'hffff_ffff_ffff; // terminate
+ rom[7] = 48'hffff_ffff_ffff; // terminate
+ rom[8] = 48'hffff_ffff_ffff; // terminate
+ rom[9] = 48'hffff_ffff_ffff; // terminate
+ rom[10] = 48'hffff_ffff_ffff; // terminate
+ rom[11] = 48'hffff_ffff_ffff; // terminate
+ rom[12] = 48'hffff_ffff_ffff; // terminate
+ rom[13] = 48'hffff_ffff_ffff; // terminate
+ rom[14] = 48'hffff_ffff_ffff; // terminate
+ rom[15] = 48'hffff_ffff_ffff; // terminate
+ end // initial begin
+
+endmodule // clock_bootstrap_rom
diff --git a/fpga/usrp2/control_lib/clock_control.v b/fpga/usrp2/control_lib/clock_control.v
new file mode 100644
index 000000000..1bbe6bd75
--- /dev/null
+++ b/fpga/usrp2/control_lib/clock_control.v
@@ -0,0 +1,115 @@
+
+
+// AD9510 Register Map (from datasheet Rev. A)
+
+/* INSTRUCTION word format (16 bits)
+ * 15 Read = 1, Write = 0
+ * 14:13 W1/W0, Number of bytes 00 - 1, 01 - 2, 10 - 3, 11 - stream
+ * 12:0 Address
+ */
+
+/* ADDR Contents Value (hex)
+ * 00 Serial Config Port 10 (def) -- MSB first, SDI/SDO separate
+ * 04 A Counter
+ * 05-06 B Counter
+ * 07-0A PLL Control
+ * 0B-0C R Divider
+ * 0D PLL Control
+ * 34-3A Fine Delay
+ * 3C-3F LVPECL Outs
+ * 40-43 LVDS/CMOS Outs
+ * 45 Clock select, power down
+ * 48-57 Dividers
+ * 58 Func and Sync
+ * 5A Update regs
+ */
+
+
+module clock_control
+ (input reset,
+ input aux_clk, // 25MHz, for before fpga clock is active
+ input clk_fpga, // real 100 MHz FPGA clock
+ output [1:0] clk_en, // controls source of reference clock
+ output [1:0] clk_sel, // controls source of reference clock
+ input clk_func, // FIXME needs to be some kind of out SYNC or reset to 9510
+ input clk_status, // Monitor PLL or SYNC status
+
+ output sen, // Enable for the AD9510
+ output sclk, // FIXME these need to be shared
+ input sdi,
+ output sdo
+ );
+
+ wire read = 1'b0; // Always write for now
+ wire [1:0] w = 2'b00; // Always send 1 byte at a time
+
+ assign clk_sel = 2'b00; // Both outputs from External Ref (SMA)
+ assign clk_en = 2'b11; // Both outputs enabled
+
+ reg [20:0] addr_data;
+
+ reg [5:0] entry;
+ reg start;
+ reg [7:0] counter;
+ reg [23:0] command;
+
+ always @*
+ case(entry)
+ 6'd00 : addr_data = {13'h00,8'h10}; // Serial setup
+ 6'd01 : addr_data = {13'h45,8'h00}; // CLK2 drives distribution, everything on
+ 6'd02 : addr_data = {13'h3D,8'h80}; // Turn on output 1, normal levels
+ 6'd03 : addr_data = {13'h4B,8'h80}; // Bypass divider 1 (div by 1)
+ 6'd04 : addr_data = {13'h08,8'h47}; // POS PFD, Dig LK Det, Charge Pump normal
+ 6'd05 : addr_data = {13'h09,8'h70}; // Max Charge Pump current
+ 6'd06 : addr_data = {13'h0A,8'h04}; // Normal operation, Prescalar Div by 2, PLL On
+ 6'd07 : addr_data = {13'h0B,8'h00}; // RDIV MSB (6 bits)
+ 6'd08 : addr_data = {13'h0C,8'h01}; // RDIV LSB (8 bits), Div by 1
+ 6'd09 : addr_data = {13'h0D,8'h00}; // Everything normal, Dig Lock Det
+ 6'd10 : addr_data = {13'h07,8'h00}; // Disable LOR detect - LOR causes failure...
+ 6'd11 : addr_data = {13'h04,8'h00}; // A Counter = Don't Care
+ 6'd12 : addr_data = {13'h05,8'h00}; // B Counter MSB = 0
+ 6'd13 : addr_data = {13'h06,8'h05}; // B Counter LSB = 5
+ default : addr_data = {13'h5A,8'h01}; // Register Update
+ endcase // case(entry)
+
+ wire [5:0] lastentry = 6'd15;
+ wire done = (counter == 8'd49);
+
+ always @(posedge aux_clk)
+ if(reset)
+ begin
+ entry <= #1 6'd0;
+ start <= #1 1'b1;
+ end
+ else if(start)
+ start <= #1 1'b0;
+ else if(done && (entry<lastentry))
+ begin
+ entry <= #1 entry + 6'd1;
+ start <= #1 1'b1;
+ end
+
+ always @(posedge aux_clk)
+ if(reset)
+ begin
+ counter <= #1 7'd0;
+ command <= #1 20'd0;
+ end
+ else if(start)
+ begin
+ counter <= #1 7'd1;
+ command <= #1 {read,w,addr_data};
+ end
+ else if( |counter && ~done )
+ begin
+ counter <= #1 counter + 7'd1;
+ if(~counter[0])
+ command <= {command[22:0],1'b0};
+ end
+
+
+ assign sen = (done | counter == 8'd0); // CSB is high when we're not doing anything
+ assign sclk = ~counter[0];
+ assign sdo = command[23];
+
+endmodule // clock_control
diff --git a/fpga/usrp2/control_lib/clock_control_tb.v b/fpga/usrp2/control_lib/clock_control_tb.v
new file mode 100644
index 000000000..4e705cf23
--- /dev/null
+++ b/fpga/usrp2/control_lib/clock_control_tb.v
@@ -0,0 +1,35 @@
+
+
+module clock_control_tb();
+
+ clock_control clock_control
+ (.reset(reset),
+ .aux_clk(aux_clk),
+ .clk_fpga(clk_fpga),
+ .clk_en(clk_en),
+ .clk_sel(clk_sel),
+ .clk_func(clk_func),
+ .clk_status(clk_status),
+
+ .sen(sen),
+ .sclk(sclk),
+ .sdi(sdi),
+ .sdo(sdo)
+ );
+
+ reg reset, aux_clk;
+
+ wire [1:0] clk_sel, clk_en;
+
+ initial reset = 1'b1;
+ initial #1000 reset = 1'b0;
+
+ initial aux_clk = 1'b0;
+ always #10 aux_clk = ~aux_clk;
+
+ initial $dumpfile("clock_control_tb.vcd");
+ initial $dumpvars(0,clock_control_tb);
+
+ initial #10000 $finish;
+
+endmodule // clock_control_tb
diff --git a/fpga/usrp2/control_lib/cmdfile b/fpga/usrp2/control_lib/cmdfile
new file mode 100644
index 000000000..cb3756cfc
--- /dev/null
+++ b/fpga/usrp2/control_lib/cmdfile
@@ -0,0 +1,18 @@
+# My stuff
+-y .
+-y ../u2_basic
+-y ../control_lib
+-y ../sdr_lib
+
+# Models
+-y ../models
+
+# Open Cores
+-y ../opencores/spi/rtl/verilog
++incdir+../opencores/spi/rtl/verilog
+-y ../opencores/wb_conbus/rtl/verilog
++incdir+../opencores/wb_conbus/rtl/verilog
+-y ../opencores/i2c/rtl/verilog
++incdir+../opencores/i2c/rtl/verilog
+-y ../opencores/aemb/rtl/verilog
+-y ../opencores/simple_gpio/rtl
diff --git a/fpga/usrp2/control_lib/dcache.v b/fpga/usrp2/control_lib/dcache.v
new file mode 100644
index 000000000..9063bf02a
--- /dev/null
+++ b/fpga/usrp2/control_lib/dcache.v
@@ -0,0 +1,165 @@
+
+module dcache
+ #(parameter AWIDTH=14,
+ parameter CWIDTH=6)
+ (input wb_clk_i,
+ input wb_rst_i,
+
+ input [AWIDTH-1:0] dwb_adr_i,
+ input dwb_stb_i,
+ input dwb_we_i,
+ input [3:0] dwb_sel_i,
+ input [31:0] dwb_dat_i,
+ output [31:0] dwb_dat_o,
+ output dwb_ack_o,
+
+ input [31:0] dram_dat_i,
+ output [31:0] dram_dat_o,
+ output [AWIDTH-1:0] dram_adr_o,
+ output dram_we_o,
+ output dram_en_o,
+ output [3:0] dram_sel_o );
+
+ localparam TAGWIDTH = AWIDTH-CWIDTH-2;
+ reg stb_d1, ack_d1, miss_d1;
+ reg [AWIDTH-1:0] held_addr;
+ reg [31:0] ddata [0:(1<<CWIDTH)-1];
+ reg [TAGWIDTH-1:0] dtags [0:(1<<CWIDTH)-1];
+ reg dvalid [0:(1<<CWIDTH)-1];
+
+ wire [CWIDTH-1:0] rd_line, wr_line;
+ wire [TAGWIDTH-1:0] wr_tags;
+ wire cache_write, invalidate;
+ wire [31:0] wr_data;
+
+ // /////////////////////////////////////
+ // Write into cache
+ integer i;
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ for(i=0;i<(1<<CWIDTH);i=i+1)
+ dvalid[i] <= 0;
+ else
+ if(invalidate)
+ dvalid[wr_line] <= 1'b0;
+ else if(cache_write)
+ dvalid[wr_line] <= 1'b1;
+
+ always @(posedge wb_clk_i)
+ if(cache_write)
+ begin
+ ddata[wr_line] <= wr_data;
+ dtags[wr_line] <= wr_tags;
+ end
+
+ // //////////////////////////////////////
+ // Read from Cache
+ wire [TAGWIDTH-1:0] tag_out = dtags[rd_line];
+ wire valid_out = dvalid[rd_line];
+ wire [31:0] data_out = ddata[rd_line];
+ wire cache_hit = valid_out & (tag_out == dwb_adr_i[AWIDTH-1:CWIDTH+2]);
+ wire cache_miss = ~cache_hit;
+
+ // //////////////////////////////////////
+ // Handle 1-cycle delay of Block-RAM
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ stb_d1 <= 0;
+ else
+ stb_d1 <= dwb_stb_i;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ held_addr <= 0;
+ else
+ held_addr <= dwb_adr_i;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ ack_d1 <= 1'b0;
+ else
+ ack_d1 <= dwb_ack_o;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ miss_d1 <= 0;
+ else
+ miss_d1 <= cache_miss;
+
+`define DC_NOCACHE
+//`define DC_BASIC
+//`define DC_FORWARDING_DP
+//`define DC_FORWARDING_SP
+//`define DC_PREFETCH
+
+`ifdef DC_NOCACHE
+ assign dwb_dat_o = dram_dat_i;
+ assign dwb_ack_o = dwb_stb_i & (dwb_we_i | (stb_d1 & ~ack_d1));
+ assign dram_adr_o = dwb_adr_i;
+ assign dram_en_o = dwb_stb_i;
+ assign dram_dat_o = dwb_dat_i;
+ assign dram_we_o = dwb_we_i;
+ assign dram_sel_o = dwb_sel_i;
+ assign rd_line = 0;
+ assign wr_line = 0;
+ assign wr_tags = 0;
+ assign wr_data = 0;
+ assign cache_write = 0;
+ assign invalidate = 0;
+`endif
+
+`ifdef DC_BASIC // Very basic, no forwarding, 2 wait states on miss
+ assign dwb_dat_o = data_out;
+ assign dwb_ack_o = dwb_stb_i & cache_hit;
+ assign dram_adr_o = dwb_adr_i;
+ assign dram_en_o = dwb_stb_i;
+ assign dram_dat_o = dwb_dat_i;
+ assign dram_we_o = dwb_we_i;
+ assign dram_sel_o = dwb_sel_i;
+ assign rd_line = dwb_adr_i[CWIDTH+1:2];
+ assign wr_line = rd_line;
+ assign wr_tags = dwb_adr_i[AWIDTH-1:CWIDTH+2];
+ assign wr_data = dwb_we_i ? dwb_dat_i : dram_dat_i;
+ assign cache_write = dwb_stb_i & (dwb_we_i | (stb_d1 & miss_d1));
+ assign invalidate = dwb_we_i & ~(&dwb_sel_i);
+`endif
+
+`ifdef DC_FORWARDING_DP // Simple forwarding, 1 wait state on miss, dual-port ram
+ assign dwb_dat_o = cache_hit ? data_out : dram_dat_i;
+ assign dwb_ack_o = dwb_stb_i & (cache_hit | (stb_d1 & ~ack_d1));
+ assign dram_adr_o = dwb_adr_i;
+ assign dram_en_o = 1'b1;
+ assign dram_dat_o = dwb_dat_i;
+ assign dram_we_o = dwb_we_i;
+ assign dram_sel_o = dwb_sel_i;
+ assign rd_line = dwb_adr_i[CWIDTH+1:2];
+ assign wr_line = held_addr[CWIDTH+1:2];
+ assign wr_tags = held_addr[AWIDTH-1:CWIDTH+2];
+ assign wr_data = dram_dat_i;
+ assign cache_write = dwb_stb_i & stb_d1 & miss_d1 & ~ack_d1;
+ assign invalidate = 0;
+`endif
+
+`ifdef DC_FORWARDING_SP // Simple forwarding, 1 wait state on miss, single-port ram
+ assign dwb_dat_o = cache_hit ? data_out : dram_dat_i;
+ assign dwb_ack_o = dwb_stb_i & (cache_hit | (stb_d1 & ~ack_d1));
+ assign dram_adr_o = dwb_adr_i;
+ assign dram_en_o = 1'b1;
+ assign dram_dat_o = dwb_dat_i;
+ assign dram_we_o = dwb_we_i;
+ assign dram_sel_o = dwb_sel_i;
+ assign rd_line = dwb_adr_i[CWIDTH+1:2];
+ assign wr_line = rd_line;
+ assign wr_tags = dwb_adr_i[AWIDTH-1:CWIDTH+2];
+ assign wr_data = dram_dat_i;
+ assign cache_write = dwb_stb_i & stb_d1 & miss_d1 & ~ack_d1;
+ assign invalidate = 0;
+`endif
+
+`ifdef DC_PREFETCH // Forwarding plus prefetch
+
+`endif
+
+
+endmodule // dcache
+
diff --git a/fpga/usrp2/control_lib/decoder_3_8.v b/fpga/usrp2/control_lib/decoder_3_8.v
new file mode 100644
index 000000000..729b45d18
--- /dev/null
+++ b/fpga/usrp2/control_lib/decoder_3_8.v
@@ -0,0 +1,21 @@
+
+module decoder_3_8
+ (input [2:0] sel,
+ output reg [7:0] res);
+
+ always @(sel or res)
+ begin
+ case (sel)
+ 3'b000 : res = 8'b00000001;
+ 3'b001 : res = 8'b00000010;
+ 3'b010 : res = 8'b00000100;
+ 3'b011 : res = 8'b00001000;
+ 3'b100 : res = 8'b00010000;
+ 3'b101 : res = 8'b00100000;
+ 3'b110 : res = 8'b01000000;
+ default : res = 8'b10000000;
+ endcase // case(sel)
+ end // always @ (sel or res)
+
+endmodule // decoder_3_8
+
diff --git a/fpga/usrp2/control_lib/dpram32.v b/fpga/usrp2/control_lib/dpram32.v
new file mode 100644
index 000000000..4da621823
--- /dev/null
+++ b/fpga/usrp2/control_lib/dpram32.v
@@ -0,0 +1,82 @@
+
+// Dual ported RAM
+// Addresses are byte-oriented, so botton 2 address bits are ignored.
+// AWIDTH of 13 allows you to address 8K bytes.
+// For Spartan 3, if the total RAM size is not a multiple of 8K then BRAM space is wasted
+// RAM_SIZE parameter allows odd-sized RAMs, like 24K
+
+module dpram32 #(parameter AWIDTH=15,
+ parameter RAM_SIZE=16384)
+ (input clk,
+
+ input [AWIDTH-1:0] adr1_i,
+ input [31:0] dat1_i,
+ output reg [31:0] dat1_o,
+ input we1_i,
+ input en1_i,
+ input [3:0] sel1_i,
+
+ input [AWIDTH-1:0] adr2_i,
+ input [31:0] dat2_i,
+ output reg [31:0] dat2_o,
+ input we2_i,
+ input en2_i,
+ input [3:0] sel2_i );
+
+ reg [7:0] ram0 [0:(RAM_SIZE/4)-1];
+ reg [7:0] ram1 [0:(RAM_SIZE/4)-1];
+ reg [7:0] ram2 [0:(RAM_SIZE/4)-1];
+ reg [7:0] ram3 [0:(RAM_SIZE/4)-1];
+
+ // This is how we used to size the RAM -->
+ // reg [7:0] ram3 [0:(1<<(AWIDTH-2))-1];
+
+ // Port 1
+ always @(posedge clk)
+ if(en1_i) dat1_o[31:24] <= ram3[adr1_i[AWIDTH-1:2]];
+ always @(posedge clk)
+ if(en1_i) dat1_o[23:16] <= ram2[adr1_i[AWIDTH-1:2]];
+ always @(posedge clk)
+ if(en1_i) dat1_o[15:8] <= ram1[adr1_i[AWIDTH-1:2]];
+ always @(posedge clk)
+ if(en1_i) dat1_o[7:0] <= ram0[adr1_i[AWIDTH-1:2]];
+
+ always @(posedge clk)
+ if(we1_i & en1_i & sel1_i[3])
+ ram3[adr1_i[AWIDTH-1:2]] <= dat1_i[31:24];
+ always @(posedge clk)
+ if(we1_i & en1_i & sel1_i[2])
+ ram2[adr1_i[AWIDTH-1:2]] <= dat1_i[23:16];
+ always @(posedge clk)
+ if(we1_i & en1_i & sel1_i[1])
+ ram1[adr1_i[AWIDTH-1:2]] <= dat1_i[15:8];
+ always @(posedge clk)
+ if(we1_i & en1_i & sel1_i[0])
+ ram0[adr1_i[AWIDTH-1:2]] <= dat1_i[7:0];
+
+ // Port 2
+ always @(posedge clk)
+ if(en2_i) dat2_o[31:24] <= ram3[adr2_i[AWIDTH-1:2]];
+ always @(posedge clk)
+ if(en2_i) dat2_o[23:16] <= ram2[adr2_i[AWIDTH-1:2]];
+ always @(posedge clk)
+ if(en2_i) dat2_o[15:8] <= ram1[adr2_i[AWIDTH-1:2]];
+ always @(posedge clk)
+ if(en2_i) dat2_o[7:0] <= ram0[adr2_i[AWIDTH-1:2]];
+
+ always @(posedge clk)
+ if(we2_i & en2_i & sel2_i[3])
+ ram3[adr2_i[AWIDTH-1:2]] <= dat2_i[31:24];
+ always @(posedge clk)
+ if(we2_i & en2_i & sel2_i[2])
+ ram2[adr2_i[AWIDTH-1:2]] <= dat2_i[23:16];
+ always @(posedge clk)
+ if(we2_i & en2_i & sel2_i[1])
+ ram1[adr2_i[AWIDTH-1:2]] <= dat2_i[15:8];
+ always @(posedge clk)
+ if(we2_i & en2_i & sel2_i[0])
+ ram0[adr2_i[AWIDTH-1:2]] <= dat2_i[7:0];
+
+endmodule // dpram32
+
+
diff --git a/fpga/usrp2/control_lib/fifo_tb.v b/fpga/usrp2/control_lib/fifo_tb.v
new file mode 100644
index 000000000..616fe4ee7
--- /dev/null
+++ b/fpga/usrp2/control_lib/fifo_tb.v
@@ -0,0 +1,151 @@
+module fifo_tb();
+
+ reg clk, rst;
+ wire short_full, short_empty, long_full, long_empty;
+ wire casc2_full, casc2_empty;
+ reg read, write;
+
+ wire [7:0] short_do, long_do;
+ wire [7:0] casc2_do;
+ reg [7:0] di;
+
+ reg clear = 0;
+
+ shortfifo #(.WIDTH(8)) shortfifo
+ (.clk(clk),.rst(rst),.datain(di),.dataout(short_do),.clear(clear),
+ .read(read),.write(write),.full(short_full),.empty(short_empty));
+
+ longfifo #(.WIDTH(8), .SIZE(4)) longfifo
+ (.clk(clk),.rst(rst),.datain(di),.dataout(long_do),.clear(clear),
+ .read(read),.write(write),.full(long_full),.empty(long_empty));
+
+ cascadefifo2 #(.WIDTH(8), .SIZE(4)) cascadefifo2
+ (.clk(clk),.rst(rst),.datain(di),.dataout(casc2_do),.clear(clear),
+ .read(read),.write(write),.full(casc2_full),.empty(casc2_empty));
+
+ initial rst = 1;
+ initial #1000 rst = 0;
+ initial clk = 0;
+ always #50 clk = ~clk;
+
+ initial di = 8'hAE;
+ initial read = 0;
+ initial write = 0;
+
+ always @(posedge clk)
+ if(write)
+ di <= di + 1;
+
+ always @(posedge clk)
+ begin
+ if(short_full != long_full)
+ $display("Error: FULL mismatch");
+ if(short_empty != long_empty)
+ $display("Note: EMPTY mismatch, usually not a problem (longfifo has 2 cycle latency)");
+ if(read & (short_do != long_do))
+ $display("Error: DATA mismatch");
+ end
+
+ initial $dumpfile("fifo_tb.vcd");
+ initial $dumpvars(0,fifo_tb);
+
+ initial
+ begin
+ @(negedge rst);
+ @(posedge clk);
+ repeat (10)
+ @(posedge clk);
+ write <= 1;
+ @(posedge clk);
+ write <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ read <= 1;
+ @(posedge clk);
+ read <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+
+ repeat(10)
+ begin
+ write <= 1;
+ @(posedge clk);
+ write <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ read <= 1;
+ @(posedge clk);
+ read <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ end // repeat (10)
+
+ write <= 1;
+ repeat (4)
+ @(posedge clk);
+ write <= 0;
+ @(posedge clk);
+ read <= 1;
+ repeat (4)
+ @(posedge clk);
+ read <= 0;
+ @(posedge clk);
+
+
+ write <= 1;
+ repeat (4)
+ @(posedge clk);
+ write <= 0;
+ @(posedge clk);
+ repeat (4)
+ begin
+ read <= 1;
+ @(posedge clk);
+ read <= 0;
+ @(posedge clk);
+ end
+
+ write <= 1;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ read <= 1;
+ repeat (5)
+ @(posedge clk);
+ write <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ read <= 0;
+ @(posedge clk);
+
+ write <= 1;
+ repeat (16)
+ @(posedge clk);
+ write <= 0;
+ @(posedge clk);
+
+ read <= 1;
+ repeat (16)
+ @(posedge clk);
+ read <= 0;
+ @(posedge clk);
+
+ repeat (10)
+ @(posedge clk);
+ $finish;
+ end
+endmodule // longfifo_tb
diff --git a/fpga/usrp2/control_lib/gray2bin.v b/fpga/usrp2/control_lib/gray2bin.v
new file mode 100644
index 000000000..5df40bd52
--- /dev/null
+++ b/fpga/usrp2/control_lib/gray2bin.v
@@ -0,0 +1,13 @@
+
+
+module gray2bin
+ #(parameter WIDTH=8)
+ (input [WIDTH-1:0] gray,
+ output reg [WIDTH-1:0] bin);
+
+ integer i;
+ always @(gray)
+ for(i = 0;i<WIDTH;i=i+1)
+ bin[i] = ^(gray>>i);
+
+endmodule // gray2bin
diff --git a/fpga/usrp2/control_lib/gray_send.v b/fpga/usrp2/control_lib/gray_send.v
new file mode 100644
index 000000000..7fc07d40c
--- /dev/null
+++ b/fpga/usrp2/control_lib/gray_send.v
@@ -0,0 +1,29 @@
+
+
+
+module gray_send
+ #(parameter WIDTH = 8)
+ (input clk_in, input [WIDTH-1:0] addr_in,
+ input clk_out, output reg [WIDTH-1:0] addr_out);
+
+ reg [WIDTH-1:0] gray_clkin, gray_clkout, gray_clkout_d1;
+ wire [WIDTH-1:0] gray, bin;
+
+ bin2gray #(.WIDTH(WIDTH)) b2g (.bin(addr_in), .gray(gray) );
+
+ always @(posedge clk_in)
+ gray_clkin <= gray;
+
+ always @(posedge clk_out)
+ gray_clkout <= gray_clkin;
+
+ always @(posedge clk_out)
+ gray_clkout_d1 <= gray_clkout;
+
+ gray2bin #(.WIDTH(WIDTH)) g2b (.gray(gray_clkout_d1), .bin(bin) );
+
+ // FIXME we may not need the next register, but it may help timing
+ always @(posedge clk_out)
+ addr_out <= bin;
+
+endmodule // gray_send
diff --git a/fpga/usrp2/control_lib/icache.v b/fpga/usrp2/control_lib/icache.v
new file mode 100644
index 000000000..bd21f47cc
--- /dev/null
+++ b/fpga/usrp2/control_lib/icache.v
@@ -0,0 +1,135 @@
+
+module icache
+ #(parameter AWIDTH=14,
+ parameter CWIDTH=6)
+
+ (input wb_clk_i,
+ input wb_rst_i,
+ input [AWIDTH-1:0] iwb_adr_i,
+ input iwb_stb_i,
+ output [31:0] iwb_dat_o,
+ output iwb_ack_o,
+ input [31:0] iram_dat_i,
+ output [AWIDTH-1:0] iram_adr_o,
+ output iram_en_o,
+ input flush);
+
+ localparam TAGWIDTH = AWIDTH-CWIDTH-2;
+ reg stb_d1, ack_d1, miss_d1;
+ reg [AWIDTH-1:0] held_addr;
+ reg [31:0] idata [0:(1<<CWIDTH)-1];
+ reg [TAGWIDTH-1:0] itags [0:(1<<CWIDTH)-1];
+ reg ivalid [0:(1<<CWIDTH)-1];
+
+ wire [CWIDTH-1:0] rd_line, wr_line;
+ wire [TAGWIDTH-1:0] wr_tags;
+ wire store_in_cache;
+
+ // /////////////////////////////////////
+ // Write into cache
+ integer i;
+ always @(posedge wb_clk_i)
+ if(wb_rst_i | flush)
+ for(i=0;i<(1<<CWIDTH);i=i+1)
+ ivalid[i] <= 0;
+ else
+ if(store_in_cache)
+ ivalid[wr_line] <= 1'b1;
+
+ always @(posedge wb_clk_i)
+ if(store_in_cache)
+ begin
+ idata[wr_line] <= iram_dat_i;
+ itags[wr_line] <= wr_tags;
+ end
+
+ // //////////////////////////////////////
+ // Read from Cache
+ wire [TAGWIDTH-1:0] tag_out = itags[rd_line];
+ wire valid_out = ivalid[rd_line];
+ wire [31:0] data_out = idata[rd_line];
+ wire cache_hit = valid_out & (tag_out == iwb_adr_i[AWIDTH-1:CWIDTH+2]);
+ wire cache_miss = ~cache_hit;
+
+ // //////////////////////////////////////
+ // Handle 1-cycle delay of Block-RAM
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ stb_d1 <= 0;
+ else
+ stb_d1 <= iwb_stb_i;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ held_addr <= 0;
+ else
+ held_addr <= iwb_adr_i;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ ack_d1 <= 1'b0;
+ else
+ ack_d1 <= iwb_ack_o;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ miss_d1 <= 0;
+ else
+ miss_d1 <= cache_miss;
+
+//`define IC_NOCACHE
+//`define IC_BASIC
+//`define IC_FORWARDING_DP
+`define IC_FORWARDING_SP
+//`define IC_PREFETCH
+
+`ifdef IC_NOCACHE
+ assign iwb_dat_o = iram_dat_i;
+ assign iwb_ack_o = iwb_stb_i & (stb_d1 & ~ack_d1);
+ assign iram_adr_o = iwb_adr_i;
+ assign iram_en_o = 1'b1;
+ assign rd_line = 0;
+ assign wr_line = 0;
+ assign wr_tags = 0;
+ assign store_in_cache = 0;
+`endif
+
+`ifdef IC_BASIC // Very basic, no forwarding, 2 wait states on miss
+ assign iwb_dat_o = data_out;
+ assign iwb_ack_o = iwb_stb_i & cache_hit;
+ assign iram_adr_o = iwb_adr_i;
+ assign iram_en_o = 1'b1;
+ assign rd_line = iwb_adr_i[CWIDTH+1:2];
+ assign wr_line = rd_line;
+ assign wr_tags = iwb_adr_i[AWIDTH-1:CWIDTH+2];
+ assign store_in_cache = stb_d1 & miss_d1;
+`endif
+
+`ifdef IC_FORWARDING_DP // Simple forwarding, 1 wait state on miss, dual-port ram
+ assign iwb_dat_o = cache_hit ? data_out : iram_dat_i;
+ assign iwb_ack_o = iwb_stb_i & (cache_hit | (stb_d1 & ~ack_d1));
+ assign iram_adr_o = iwb_adr_i;
+ assign iram_en_o = 1'b1;
+ assign rd_line = iwb_adr_i[CWIDTH+1:2];
+ assign wr_line = held_addr[CWIDTH+1:2];
+ assign wr_tags = held_addr[AWIDTH-1:CWIDTH+2];
+ assign store_in_cache = iwb_stb_i & stb_d1 & miss_d1 & ~ack_d1;
+`endif
+
+`ifdef IC_FORWARDING_SP // Simple forwarding, 1 wait state on miss, single-port ram
+ assign iwb_dat_o = cache_hit ? data_out : iram_dat_i;
+ assign iwb_ack_o = iwb_stb_i & (cache_hit | (stb_d1 & ~ack_d1));
+ assign iram_adr_o = iwb_adr_i;
+ assign iram_en_o = 1'b1;
+ assign rd_line = iwb_adr_i[CWIDTH+1:2];
+ assign wr_line = rd_line;
+ assign wr_tags = iwb_adr_i[AWIDTH-1:CWIDTH+2];
+ assign store_in_cache = iwb_stb_i & stb_d1 & miss_d1 & ~ack_d1;
+`endif
+
+`ifdef IC_PREFETCH // Forwarding plus prefetch
+
+`endif
+
+
+endmodule // icache
diff --git a/fpga/usrp2/control_lib/longfifo.v b/fpga/usrp2/control_lib/longfifo.v
new file mode 100644
index 000000000..bf3338e0b
--- /dev/null
+++ b/fpga/usrp2/control_lib/longfifo.v
@@ -0,0 +1,150 @@
+
+// FIFO intended to be interchangeable with shortfifo, but
+// based on block ram instead of SRL16's
+// only one clock domain
+
+// Port A is write port, Port B is read port
+
+module longfifo
+ #(parameter WIDTH=32, SIZE=9)
+ (input clk, input rst,
+ input [WIDTH-1:0] datain,
+ output [WIDTH-1:0] dataout,
+ input read,
+ input write,
+ input clear,
+ output full,
+ output empty,
+ output reg [15:0] space,
+ output reg [15:0] occupied);
+
+ // Read side states
+ localparam EMPTY = 0;
+ localparam PRE_READ = 1;
+ localparam READING = 2;
+
+ reg [SIZE-1:0] wr_addr, rd_addr;
+ reg [1:0] read_state;
+
+ reg empty_reg, full_reg;
+ always @(posedge clk)
+ if(rst)
+ wr_addr <= 0;
+ else if(clear)
+ wr_addr <= 0;
+ else if(write)
+ wr_addr <= wr_addr + 1;
+
+ ram_2port #(.DWIDTH(WIDTH),.AWIDTH(SIZE))
+ ram (.clka(clk),
+ .ena(1'b1),
+ .wea(write),
+ .addra(wr_addr),
+ .dia(datain),
+ .doa(),
+
+ .clkb(clk),
+ .enb((read_state==PRE_READ)|read),
+ .web(0),
+ .addrb(rd_addr),
+ .dib(0),
+ .dob(dataout));
+
+ always @(posedge clk)
+ if(rst)
+ begin
+ read_state <= EMPTY;
+ rd_addr <= 0;
+ empty_reg <= 1;
+ end
+ else
+ if(clear)
+ begin
+ read_state <= EMPTY;
+ rd_addr <= 0;
+ empty_reg <= 1;
+ end
+ else
+ case(read_state)
+ EMPTY :
+ if(write)
+ begin
+ //rd_addr <= wr_addr;
+ read_state <= PRE_READ;
+ end
+ PRE_READ :
+ begin
+ read_state <= READING;
+ empty_reg <= 0;
+ rd_addr <= rd_addr + 1;
+ end
+
+ READING :
+ if(read)
+ if(rd_addr == wr_addr)
+ begin
+ empty_reg <= 1;
+ if(write)
+ read_state <= PRE_READ;
+ else
+ read_state <= EMPTY;
+ end
+ else
+ rd_addr <= rd_addr + 1;
+ endcase // case(read_state)
+
+ wire [SIZE-1:0] dont_write_past_me = rd_addr - 3;
+ wire becoming_full = wr_addr == dont_write_past_me;
+
+ always @(posedge clk)
+ if(rst)
+ full_reg <= 0;
+ else if(clear)
+ full_reg <= 0;
+ else if(read & ~write)
+ full_reg <= 0;
+ //else if(write & ~read & (wr_addr == (rd_addr-3)))
+ else if(write & ~read & becoming_full)
+ full_reg <= 1;
+
+ //assign empty = (read_state != READING);
+ assign empty = empty_reg;
+
+ // assign full = ((rd_addr - 1) == wr_addr);
+ assign full = full_reg;
+
+ //////////////////////////////////////////////
+ // space and occupied are for diagnostics only
+ // not guaranteed exact
+
+ localparam NUMLINES = (1<<SIZE)-2;
+ always @(posedge clk)
+ if(rst)
+ space <= NUMLINES;
+ else if(clear)
+ space <= NUMLINES;
+ else if(read & ~write)
+ space <= space + 1;
+ else if(write & ~read)
+ space <= space - 1;
+
+ always @(posedge clk)
+ if(rst)
+ occupied <= 0;
+ else if(clear)
+ occupied <= 0;
+ else if(read & ~write)
+ occupied <= occupied - 1;
+ else if(write & ~read)
+ occupied <= occupied + 1;
+
+ /*
+ wire [SIZE-1:0] fullness = wr_addr - rd_addr; // Approximate, for simulation only
+ assign occupied = {{16-SIZE{1'b0}},fullness};
+
+ wire [SIZE-1:0] free_space = rd_addr - wr_addr - 2; // Approximate, for SERDES flow control
+ assign space = {{16-SIZE{1'b0}},free_space};
+ */
+
+
+endmodule // longfifo
diff --git a/fpga/usrp2/control_lib/medfifo.v b/fpga/usrp2/control_lib/medfifo.v
new file mode 100644
index 000000000..5a77e8c16
--- /dev/null
+++ b/fpga/usrp2/control_lib/medfifo.v
@@ -0,0 +1,49 @@
+
+module medfifo
+ #(parameter WIDTH=32,
+ parameter DEPTH=1)
+ (input clk, input rst,
+ input [WIDTH-1:0] datain,
+ output [WIDTH-1:0] dataout,
+ input read,
+ input write,
+ input clear,
+ output full,
+ output empty,
+ output [7:0] space,
+ output [7:0] occupied);
+
+ localparam NUM_FIFOS = (1<<DEPTH);
+
+ wire [WIDTH-1:0] dout [0:NUM_FIFOS-1];
+ wire [0:NUM_FIFOS-1] full_x;
+ wire [0:NUM_FIFOS-1] empty_x;
+
+ shortfifo #(.WIDTH(WIDTH))
+ head (.clk(clk),.rst(rst),
+ .datain(datain),.write(write),.full(full),
+ .dataout(dout[0]),.read(~empty_x[0] & ~full_x[1]),.empty(empty_x[0]),
+ .clear(clear),.space(space[4:0]),.occupied() );
+
+ shortfifo #(.WIDTH(WIDTH))
+ tail (.clk(clk),.rst(rst),
+ .datain(dout[NUM_FIFOS-2]),.write(~empty_x[NUM_FIFOS-2] & ~full_x[NUM_FIFOS-1]),.full(full_x[NUM_FIFOS-1]),
+ .dataout(dataout),.read(read),.empty(empty),
+ .clear(clear),.space(),.occupied(occupied[4:0]) );
+
+ genvar i;
+ generate
+ for(i = 1; i < NUM_FIFOS-1 ; i = i + 1)
+ begin : gen_depth
+ shortfifo #(.WIDTH(WIDTH))
+ shortfifo (.clk(clk),.rst(rst),
+ .datain(dout[i-1]),.write(~full_x[i] & ~empty_x[i-1]),.full(full_x[i]),
+ .dataout(dout[i]),.read(~full_x[i+1] & ~empty_x[i]),.empty(empty_x[i]),
+ .clear(clear),.space(),.occupied() );
+ end
+ endgenerate
+
+ assign space[7:5] = 0;
+ assign occupied[7:5] = 0;
+
+endmodule // medfifo
diff --git a/fpga/usrp2/control_lib/mux4.v b/fpga/usrp2/control_lib/mux4.v
new file mode 100644
index 000000000..31c85c832
--- /dev/null
+++ b/fpga/usrp2/control_lib/mux4.v
@@ -0,0 +1,16 @@
+
+
+module mux4
+ #(parameter WIDTH=32, parameter DISABLED=0)
+ (input en,
+ input [1:0] sel,
+ input [WIDTH-1:0] i0,
+ input [WIDTH-1:0] i1,
+ input [WIDTH-1:0] i2,
+ input [WIDTH-1:0] i3,
+ output [WIDTH-1:0] o);
+
+ assign o = en ? (sel[1] ? (sel[0] ? i3 : i2) : (sel[0] ? i1 : i0)) :
+ DISABLED;
+
+endmodule // mux4
diff --git a/fpga/usrp2/control_lib/mux8.v b/fpga/usrp2/control_lib/mux8.v
new file mode 100644
index 000000000..9db96a60f
--- /dev/null
+++ b/fpga/usrp2/control_lib/mux8.v
@@ -0,0 +1,21 @@
+
+
+module mux8
+ #(parameter WIDTH=32, parameter DISABLED=0)
+ (input en,
+ input [2:0] sel,
+ input [WIDTH-1:0] i0,
+ input [WIDTH-1:0] i1,
+ input [WIDTH-1:0] i2,
+ input [WIDTH-1:0] i3,
+ input [WIDTH-1:0] i4,
+ input [WIDTH-1:0] i5,
+ input [WIDTH-1:0] i6,
+ input [WIDTH-1:0] i7,
+ output [WIDTH-1:0] o);
+
+ assign o = en ? (sel[2] ? (sel[1] ? (sel[0] ? i7 : i6) : (sel[0] ? i5 : i4)) :
+ (sel[1] ? (sel[0] ? i3 : i2) : (sel[0] ? i1 : i0))) :
+ DISABLED;
+
+endmodule // mux8
diff --git a/fpga/usrp2/control_lib/mux_32_4.v b/fpga/usrp2/control_lib/mux_32_4.v
new file mode 100644
index 000000000..fef5812e9
--- /dev/null
+++ b/fpga/usrp2/control_lib/mux_32_4.v
@@ -0,0 +1,13 @@
+
+
+module mux_32_4
+ (input [1:0] sel,
+ input [31:0] in0,
+ input [31:0] in1,
+ input [31:0] in2,
+ input [31:0] in3,
+ output [31:0] out);
+
+ assign out = sel[1] ? (sel[0] ? in3 : in2) : (sel[0] ? in1 : in0);
+
+endmodule // mux_32_4
diff --git a/fpga/usrp2/control_lib/newfifo/.gitignore b/fpga/usrp2/control_lib/newfifo/.gitignore
new file mode 100644
index 000000000..cba7efc8e
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/.gitignore
@@ -0,0 +1 @@
+a.out
diff --git a/fpga/usrp2/control_lib/newfifo/buffer_int.v b/fpga/usrp2/control_lib/newfifo/buffer_int.v
new file mode 100644
index 000000000..b45ed3532
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/buffer_int.v
@@ -0,0 +1,168 @@
+
+// FIFO Interface to the 2K buffer RAMs
+// Read port is read-acknowledge
+// FIXME do we want to be able to interleave reads and writes?
+
+module buffer_int
+ #(parameter BUF_NUM = 0,
+ parameter BUF_SIZE = 9)
+ (// Control Interface
+ input clk,
+ input rst,
+ input [31:0] ctrl_word,
+ input go,
+ output done,
+ output error,
+ output idle,
+ output [1:0] flag,
+
+ // Buffer Interface
+ output en_o,
+ output we_o,
+ output reg [BUF_SIZE-1:0] addr_o,
+ output [31:0] dat_to_buf,
+ input [31:0] dat_from_buf,
+
+ // Write FIFO Interface
+ input [31:0] wr_data_i,
+ input [3:0] wr_flags_i,
+ input wr_ready_i,
+ output wr_ready_o,
+
+ // Read FIFO Interface
+ output [31:0] rd_data_o,
+ output [3:0] rd_flags_o,
+ output rd_ready_o,
+ input rd_ready_i
+ );
+
+ reg [31:0] ctrl_reg;
+ reg go_reg;
+
+ always @(posedge clk)
+ go_reg <= go;
+
+ always @(posedge clk)
+ if(rst)
+ ctrl_reg <= 0;
+ else
+ if(go & (ctrl_word[31:28] == BUF_NUM))
+ ctrl_reg <= ctrl_word;
+
+ wire [BUF_SIZE-1:0] firstline = ctrl_reg[BUF_SIZE-1:0];
+ wire [BUF_SIZE-1:0] lastline = ctrl_reg[2*BUF_SIZE-1:BUF_SIZE];
+
+ wire read = ctrl_reg[22];
+ wire write = ctrl_reg[23];
+ wire clear = ctrl_reg[24];
+ //wire [2:0] port = ctrl_reg[27:25]; // Ignored in this block
+ //wire [3:0] buff_num = ctrl_reg[31:28]; // Ignored here ?
+
+ localparam IDLE = 3'd0;
+ localparam PRE_READ = 3'd1;
+ localparam READING = 3'd2;
+ localparam WRITING = 3'd3;
+ localparam ERROR = 3'd4;
+ localparam DONE = 3'd5;
+
+ reg [2:0] state;
+ reg rd_sop, rd_eop;
+ wire wr_sop, wr_eop, wr_error;
+ reg [1:0] rd_occ;
+ wire [1:0] wr_occ;
+
+ always @(posedge clk)
+ if(rst)
+ begin
+ state <= IDLE;
+ rd_sop <= 0;
+ rd_eop <= 0;
+ rd_occ <= 0;
+ end
+ else
+ if(clear)
+ begin
+ state <= IDLE;
+ rd_sop <= 0;
+ rd_eop <= 0;
+ rd_occ <= 0;
+ end
+ else
+ case(state)
+ IDLE :
+ if(go_reg & read)
+ begin
+ addr_o <= firstline;
+ state <= PRE_READ;
+ end
+ else if(go_reg & write)
+ begin
+ addr_o <= firstline;
+ state <= WRITING;
+ end
+
+ PRE_READ :
+ begin
+ state <= READING;
+ addr_o <= addr_o + 1;
+ rd_occ <= 2'b00;
+ rd_sop <= 1;
+ rd_eop <= 0;
+ end
+
+ READING :
+ if(rd_ready_i)
+ begin
+ rd_sop <= 0;
+ addr_o <= addr_o + 1;
+ if(addr_o == lastline)
+ begin
+ rd_eop <= 1;
+ // FIXME assign occ here
+ rd_occ <= 0;
+ end
+ else
+ rd_eop <= 0;
+ if(rd_eop)
+ state <= DONE;
+ end
+
+ WRITING :
+ begin
+ if(wr_ready_i)
+ begin
+ addr_o <= addr_o + 1;
+ if(wr_error)
+ begin
+ state <= ERROR;
+ // Save OCC flags here
+ end
+ else if((addr_o == lastline)||wr_eop)
+ state <= DONE;
+ end // if (wr_ready_i)
+ end // case: WRITING
+
+ endcase // case(state)
+
+ assign dat_to_buf = wr_data_i;
+ assign rd_data_o = dat_from_buf;
+
+ assign rd_flags_o = { rd_occ[1:0], rd_eop, rd_sop };
+ assign rd_ready_o = (state == READING);
+
+ assign wr_sop = wr_flags_i[0];
+ assign wr_eop = wr_flags_i[1];
+ assign wr_occ = wr_flags_i[3:2];
+ assign wr_error = wr_sop & wr_eop;
+ assign wr_ready_o = (state == WRITING);
+
+ assign we_o = (state == WRITING);
+ //assign we_o = (state == WRITING) && wr_ready_i; // always write to avoid timing issue
+
+ assign en_o = ~((state==READING)& ~rd_ready_i); // FIXME potential critical path
+
+ assign done = (state == DONE);
+ assign error = (state == ERROR);
+ assign idle = (state == IDLE);
+
+endmodule // buffer_int
diff --git a/fpga/usrp2/control_lib/newfifo/buffer_int_tb.v b/fpga/usrp2/control_lib/newfifo/buffer_int_tb.v
new file mode 100644
index 000000000..df54dcc0b
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/buffer_int_tb.v
@@ -0,0 +1,418 @@
+
+module buffer_int_tb ();
+
+ reg clk = 0;
+ reg rst = 1;
+
+ initial #100 rst = 0;
+ always #5 clk = ~clk;
+
+ wire en, we;
+ wire [8:0] addr;
+ wire [31:0] fifo2buf, buf2fifo;
+
+ wire [31:0] rd_data_o;
+ wire [3:0] rd_flags_o;
+ wire rd_sop_o, rd_eop_o;
+ reg rd_error_i = 0, rd_read_i = 0;
+
+ reg [31:0] wr_data_i = 0;
+ wire [3:0] wr_flags_i;
+ reg wr_eop_i = 0, wr_sop_i = 0;
+ reg wr_write_i = 0;
+ wire wr_ready_o, wr_full_o;
+
+ reg clear = 0, write = 0, read = 0;
+ reg [8:0] firstline = 0, lastline = 0;
+ wire [3:0] step = 1;
+ wire [31:0] ctrl_word = {4'b0,3'b0,clear,write,read,step,lastline,firstline};
+ reg go = 0;
+ wire done, error;
+
+ assign wr_flags_i = {2'b00, wr_eop_i, wr_sop_i};
+ assign rd_sop_o = rd_flags_o[0];
+ assign rd_eop_o = rd_flags_o[1];
+
+ buffer_int buffer_int
+ (.clk(clk),.rst(rst),
+ .ctrl_word(ctrl_word),.go(go),
+ .done(done),.error(error),
+
+ // Buffer Interface
+ .en_o(en),.we_o(we),.addr_o(addr),
+ .dat_to_buf(fifo2buf),.dat_from_buf(buf2fifo),
+
+ // Write FIFO Interface
+ .wr_data_i(wr_data_i), .wr_flags_i(wr_flags_i), .wr_write_i(wr_write_i), .wr_ready_o(wr_ready_o),
+
+ // Read FIFO Interface
+ .rd_data_o(rd_data_o), .rd_flags_o(rd_flags_o), .rd_ready_o(rd_ready_o), .rd_read_i(rd_read_i)
+ );
+
+ reg ram_en = 0, ram_we = 0;
+ reg [8:0] ram_addr = 0;
+ reg [31:0] ram_data = 0;
+
+ ram_2port #(.DWIDTH(32),.AWIDTH(9)) ram_2port
+ (.clka(clk), .ena(ram_en), .wea(ram_we), .addra(ram_addr), .dia(ram_data), .doa(),
+ .clkb(clk), .enb(en), .web(we), .addrb(addr), .dib(fifo2buf), .dob(buf2fifo) );
+
+ initial
+ begin
+ @(negedge rst);
+ @(posedge clk);
+ FillRAM;
+
+ ResetBuffer;
+ SetBufferRead(5,10);
+ $display("Testing full read, no wait states.");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(6,0);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(5,10);
+ $display("Testing full read, 2 wait states.");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(6,2);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(5,10);
+ $display("Testing partial read, 0 wait states, then nothing after last.");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(3,0);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(5,10);
+ $display("Testing partial read, 0 wait states, then done at same time as last.");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(2,0);
+ ReadALine;
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(5,10);
+ $display("Testing partial read, 3 wait states, then error at same time as last.");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(2,3);
+ rd_error_i <= 1;
+ ReadALine;
+ rd_error_i <= 0;
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(500,511);
+ $display("Testing full read, to the end of the buffer.");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(12,0);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(0,511);
+ $display("Testing full read, start to end of the buffer.");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(512,0);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(505,3);
+ $display("Testing full read, wraparound");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(11,0);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferWrite(10,15);
+ $display("Testing Full Write, no wait states");
+ while(!wr_ready_o)
+ @(posedge clk);
+ WriteLines(6,0,72);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferWrite(18,23);
+ $display("Testing Full Write, 1 wait states");
+ while(!wr_ready_o)
+ @(posedge clk);
+ WriteLines(6,1,101);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferWrite(27,40);
+ $display("Testing Partial Write, 0 wait states");
+ while(!wr_ready_o)
+ @(posedge clk);
+ WriteLines(6,0,201);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferWrite(45,200);
+ $display("Testing Partial Write, 0 wait states, then done and write simultaneously");
+ while(!wr_ready_o)
+ @(posedge clk);
+ wr_sop_i <= 1; wr_eop_i <= 0;
+ WriteLines(6,0,301);
+ wr_sop_i <= 0; wr_eop_i <= 1;
+ WriteALine(400);
+ wr_sop_i <= 0; wr_eop_i <= 0;
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferWrite(55,200);
+ $display("Testing Partial Write, 0 wait states, then error");
+ while(!wr_ready_o)
+ @(posedge clk);
+ WriteLines(6,0,501);
+ wr_sop_i <= 1; wr_eop_i <= 1;
+ WriteALine(400);
+ @(posedge clk);
+ repeat (10)
+ @(posedge clk);
+ wr_sop_i <= 0; wr_eop_i <= 0;
+
+ ResetBuffer;
+ SetBufferRead(0,82);
+ $display("Testing read after all the writes");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(83,0);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferWrite(508,4);
+ $display("Testing wraparound write");
+ while(!wr_ready_o)
+ @(posedge clk);
+ WriteLines(9,0,601);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(506,10);
+ $display("Reading wraparound write");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(17,0);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferWrite(0,511);
+ $display("Testing Whole Buffer write");
+ while(!wr_ready_o)
+ @(posedge clk);
+ WriteLines(512,0,1000);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(0,511);
+ $display("Reading Whole Buffer write");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(512,0);
+ repeat (10)
+ @(posedge clk);
+
+ /*
+ ResetBuffer;
+ SetBufferWrite(5,10);
+ $display("Testing Write Too Many");
+ while(!wr_ready_o)
+ @(posedge clk);
+ WriteLines(12,0,2000);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(0,15);
+ $display("Reading back Write Too Many");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(16,0);
+ repeat (10)
+ @(posedge clk);
+ */
+ ResetBuffer;
+ SetBufferWrite(15,20);
+ $display("Testing Write One Less Than Full");
+ while(!wr_ready_o)
+ @(posedge clk);
+ wr_sop_i <= 1; wr_eop_i <= 0;
+ WriteALine(400);
+ wr_sop_i <= 0; wr_eop_i <= 0;
+ WriteLines(3,0,2000);
+ wr_sop_i <= 0; wr_eop_i <= 1;
+ WriteALine(400);
+ wr_sop_i <= 0; wr_eop_i <= 0;
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ SetBufferRead(13,22);
+ $display("Reading back Write One Less Than Full");
+ while(!rd_sop_o)
+ @(posedge clk);
+ ReadLines(10,0);
+ repeat (10)
+ @(posedge clk);
+
+ ResetBuffer;
+ repeat(100)
+ @(posedge clk);
+ $finish;
+ end
+
+ always @(posedge clk)
+ if(rd_read_i == 1'd1)
+ $display("READ Buffer %d, rd_sop_o %d, rd_eop_o %d", rd_data_o, rd_sop_o, rd_eop_o);
+
+ always @(posedge clk)
+ if(wr_write_i == 1'd1)
+ $display("WRITE Buffer %d, wr_ready_o %d, wr_full_o %d", wr_data_i, wr_ready_o, wr_full_o);
+
+ initial begin
+ $dumpfile("buffer_int_tb.lxt");
+ $dumpvars(0,buffer_int_tb);
+ end
+
+ task FillRAM;
+ begin
+ ram_addr <= 0;
+ ram_data <= 0;
+ @(posedge clk);
+ ram_en <= 1;
+ ram_we <= 1;
+ @(posedge clk);
+ repeat (511)
+ begin
+ ram_addr <= ram_addr + 1;
+ ram_data <= ram_data + 1;
+ ram_en <= 1;
+ ram_we <= 1;
+ @(posedge clk);
+ end
+ ram_en <= 0;
+ ram_we <= 0;
+ @(posedge clk);
+ $display("Filled the RAM");
+ end
+ endtask // FillRAM
+
+ task ResetBuffer;
+ begin
+ clear <= 1; read <= 0; write <= 0;
+ go <= 1;
+ @(posedge clk);
+ go <= 0;
+ @(posedge clk);
+ $display("Buffer Reset");
+ end
+ endtask // ClearBuffer
+
+ task SetBufferWrite;
+ input [8:0] start;
+ input [8:0] stop;
+ begin
+ clear <= 0; read <= 0; write <= 1;
+ firstline <= start;
+ lastline <= stop;
+ go <= 1;
+ @(posedge clk);
+ go <= 0;
+ @(posedge clk);
+ $display("Buffer Set for Write");
+ end
+ endtask // SetBufferWrite
+
+ task SetBufferRead;
+ input [8:0] start;
+ input [8:0] stop;
+ begin
+ clear <= 0; read <= 1; write <= 0;
+ firstline <= start;
+ lastline <= stop;
+ go <= 1;
+ @(posedge clk);
+ go <= 0;
+ @(posedge clk);
+ $display("Buffer Set for Read");
+ end
+ endtask // SetBufferRead
+
+ task ReadALine;
+ begin
+ while(~rd_ready_o)
+ @(posedge clk);
+ #1 rd_read_i <= 1;
+ @(posedge clk);
+ rd_read_i <= 0;
+ end
+ endtask // ReadALine
+
+ task ReadLines;
+ input [9:0] lines;
+ input [7:0] wait_states;
+ begin
+ $display("Read Lines: Number %d, Wait States %d",lines,wait_states);
+ repeat (lines)
+ begin
+ ReadALine;
+ repeat (wait_states)
+ @(posedge clk);
+ end
+ end
+ endtask // ReadLines
+
+ task WriteALine;
+ input [31:0] value;
+ begin
+ while(~wr_ready_o)
+ @(posedge clk);
+ #1 wr_write_i <= 1;
+ wr_data_i <= value;
+ @(posedge clk);
+ wr_write_i <= 0;
+ end
+ endtask // WriteALine
+
+ task WriteLines;
+ input [9:0] lines;
+ input [7:0] wait_states;
+ input [31:0] value;
+ begin
+ $display("Write Lines: Number %d, Wait States %d",lines,wait_states);
+ repeat(lines)
+ begin
+ value <= value + 1;
+ WriteALine(value);
+ repeat(wait_states)
+ @(posedge clk);
+ end
+ end
+ endtask // WriteLines
+
+endmodule // buffer_int_tb
diff --git a/fpga/usrp2/control_lib/newfifo/buffer_pool.v b/fpga/usrp2/control_lib/newfifo/buffer_pool.v
new file mode 100644
index 000000000..41ac1deb3
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/buffer_pool.v
@@ -0,0 +1,283 @@
+
+// Buffer pool. Contains 8 buffers, each 2K (512 by 32). Each buffer
+// is a dual-ported RAM. Port A on each of them is indirectly connected
+// to the wishbone bus by a bridge. Port B may be connected any one of the
+// 8 (4 rd, 4 wr) FIFO-like streaming interaces, or disconnected. The wishbone bus
+// provides access to all 8 buffers, and also controls the connections
+// between the ports and the buffers, allocating them as needed.
+
+// wb_adr is 16 bits --
+// bits 13:11 select which buffer
+// bits 10:2 select line in buffer
+// bits 1:0 are unused (32-bit access only)
+
+// BUF_SIZE is in address lines (i.e. log2 of number of lines).
+// For S3 it should be 9 (512 words, 2KB)
+// For V5 it should be at least 10 (1024 words, 4KB) or 11 (2048 words, 8KB)
+
+module buffer_pool
+ #(parameter BUF_SIZE = 9,
+ parameter SET_ADDR = 64)
+ (input wb_clk_i,
+ input wb_rst_i,
+ input wb_we_i,
+ input wb_stb_i,
+ input [15:0] wb_adr_i,
+ input [31:0] wb_dat_i,
+ output [31:0] wb_dat_o,
+ output reg wb_ack_o,
+ output wb_err_o,
+ output wb_rty_o,
+
+ input stream_clk,
+ input stream_rst,
+
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ output [31:0] status,
+ output sys_int_o,
+
+ output [31:0] s0, output [31:0] s1, output [31:0] s2, output [31:0] s3,
+ output [31:0] s4, output [31:0] s5, output [31:0] s6, output [31:0] s7,
+
+ // Write Interfaces
+ input [31:0] wr0_data_i, input [3:0] wr0_flags_i, input wr0_ready_i, output wr0_ready_o,
+ input [31:0] wr1_data_i, input [3:0] wr1_flags_i, input wr1_ready_i, output wr1_ready_o,
+ input [31:0] wr2_data_i, input [3:0] wr2_flags_i, input wr2_ready_i, output wr2_ready_o,
+ input [31:0] wr3_data_i, input [3:0] wr3_flags_i, input wr3_ready_i, output wr3_ready_o,
+
+ // Read Interfaces
+ output [31:0] rd0_data_o, output [3:0] rd0_flags_o, output rd0_ready_o, input rd0_ready_i,
+ output [31:0] rd1_data_o, output [3:0] rd1_flags_o, output rd1_ready_o, input rd1_ready_i,
+ output [31:0] rd2_data_o, output [3:0] rd2_flags_o, output rd2_ready_o, input rd2_ready_i,
+ output [31:0] rd3_data_o, output [3:0] rd3_flags_o, output rd3_ready_o, input rd3_ready_i
+ );
+
+ wire [7:0] sel_a;
+
+ wire [BUF_SIZE-1:0] buf_addra = wb_adr_i[BUF_SIZE+1:2]; // ignore address 1:0, 32-bit access only
+ wire [2:0] which_buf = wb_adr_i[BUF_SIZE+4:BUF_SIZE+2]; // address 15:14 selects the buffer pool
+
+ decoder_3_8 dec(.sel(which_buf),.res(sel_a));
+
+ genvar i;
+
+ wire go;
+
+ reg [2:0] port[0:7];
+ reg [3:0] read_src[0:3];
+ reg [3:0] write_src[0:3];
+
+ wire [7:0] done;
+ wire [7:0] error;
+ wire [7:0] idle;
+
+ wire [31:0] buf_doa[0:7];
+
+ wire [7:0] buf_enb;
+ wire [7:0] buf_web;
+ wire [BUF_SIZE-1:0] buf_addrb[0:7];
+ wire [31:0] buf_dib[0:7];
+ wire [31:0] buf_dob[0:7];
+
+ wire [31:0] wr_data_i[0:7];
+ wire [3:0] wr_flags_i[0:7];
+ wire [7:0] wr_ready_i;
+ wire [7:0] wr_ready_o;
+
+ wire [31:0] rd_data_o[0:7];
+ wire [3:0] rd_flags_o[0:7];
+ wire [7:0] rd_ready_o;
+ wire [7:0] rd_ready_i;
+
+ assign status = {8'd0,idle[7:0],error[7:0],done[7:0]};
+
+ assign s0 = buf_addrb[0];
+ assign s1 = buf_addrb[1];
+ assign s2 = buf_addrb[2];
+ assign s3 = buf_addrb[3];
+ assign s4 = buf_addrb[4];
+ assign s5 = buf_addrb[5];
+ assign s6 = buf_addrb[6];
+ assign s7 = buf_addrb[7];
+
+ wire [31:0] fifo_ctrl;
+ setting_reg #(.my_addr(SET_ADDR))
+ sreg(.clk(stream_clk),.rst(stream_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(fifo_ctrl),.changed(go));
+
+ integer k;
+ always @(posedge stream_clk)
+ if(stream_rst)
+ for(k=0;k<8;k=k+1)
+ port[k] <= 4; // disabled
+ else
+ for(k=0;k<8;k=k+1)
+ if(go & (fifo_ctrl[31:28]==k))
+ port[k] <= fifo_ctrl[27:25];
+
+ always @(posedge stream_clk)
+ if(stream_rst)
+ for(k=0;k<4;k=k+1)
+ read_src[k] <= 8; // disabled
+ else
+ for(k=0;k<4;k=k+1)
+ if(go & fifo_ctrl[22] & (fifo_ctrl[27:25]==k))
+ read_src[k] <= fifo_ctrl[31:28];
+
+ always @(posedge stream_clk)
+ if(stream_rst)
+ for(k=0;k<4;k=k+1)
+ write_src[k] <= 8; // disabled
+ else
+ for(k=0;k<4;k=k+1)
+ if(go & fifo_ctrl[23] & (fifo_ctrl[27:25]==k))
+ write_src[k] <= fifo_ctrl[31:28];
+
+ generate
+ for(i=0;i<8;i=i+1)
+ begin : gen_buffer
+ RAMB16_S36_S36 dpram
+ (.DOA(buf_doa[i]),.ADDRA(buf_addra),.CLKA(wb_clk_i),.DIA(wb_dat_i),.DIPA(4'h0),
+ .ENA(wb_stb_i & sel_a[i]),.SSRA(0),.WEA(wb_we_i),
+ .DOB(buf_dob[i]),.ADDRB(buf_addrb[i]),.CLKB(stream_clk),.DIB(buf_dib[i]),.DIPB(4'h0),
+ .ENB(buf_enb[i]),.SSRB(0),.WEB(buf_web[i]) );
+
+/*
+ ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer
+ (.clka(wb_clk_i),.ena(wb_stb_i & sel_a[i]),.wea(wb_we_i),
+ .addra(buf_addra),.dia(wb_dat_i),.doa(buf_doa[i]),
+ .clkb(stream_clk),.enb(buf_enb[i]),.web(buf_web[i]),
+ .addrb(buf_addrb[i]),.dib(buf_dib[i]),.dob(buf_dob[i]));
+
+ */
+
+ buffer_int #(.BUF_NUM(i),.BUF_SIZE(BUF_SIZE)) buffer_int
+ (.clk(stream_clk),.rst(stream_rst),
+ .ctrl_word(fifo_ctrl),.go(go & (fifo_ctrl[31:28]==i)),
+ .done(done[i]),.error(error[i]),.idle(idle[i]),
+ .en_o(buf_enb[i]),
+ .we_o(buf_web[i]),
+ .addr_o(buf_addrb[i]),
+ .dat_to_buf(buf_dib[i]),
+ .dat_from_buf(buf_dob[i]),
+ .wr_data_i(wr_data_i[i]),
+ .wr_flags_i(wr_flags_i[i]),
+ .wr_ready_i(wr_ready_i[i]),
+ .wr_ready_o(wr_ready_o[i]),
+ .rd_data_o(rd_data_o[i]),
+ .rd_flags_o(rd_flags_o[i]),
+ .rd_ready_o(rd_ready_o[i]),
+ .rd_ready_i(rd_ready_i[i]) );
+ mux4 #(.WIDTH(37))
+ mux4_wr (.en(~port[i][2]),.sel(port[i][1:0]),
+ .i0({wr0_data_i,wr0_flags_i,wr0_ready_i}),
+ .i1({wr1_data_i,wr1_flags_i,wr1_ready_i}),
+ .i2({wr2_data_i,wr2_flags_i,wr2_ready_i}),
+ .i3({wr3_data_i,wr3_flags_i,wr3_ready_i}),
+ .o({wr_data_i[i],wr_flags_i[i],wr_ready_i[i]}) );
+ mux4 #(.WIDTH(1))
+ mux4_rd (.en(~port[i][2]),.sel(port[i][1:0]),
+ .i0(rd0_ready_i),.i1(rd1_ready_i),.i2(rd2_ready_i),.i3(rd3_ready_i),
+ .o(rd_ready_i[i]));
+ end // block: gen_buffer
+ endgenerate
+
+ //----------------------------------------------------------------------
+ // Wishbone Outputs
+
+ // Use the following lines if ram output and mux can be made fast enough
+
+ assign wb_err_o = 1'b0; // Unused for now
+ assign wb_rty_o = 1'b0; // Unused for now
+
+ always @(posedge wb_clk_i)
+ wb_ack_o <= wb_stb_i & ~wb_ack_o;
+ assign wb_dat_o = buf_doa[which_buf];
+
+ // Use this if we can't make the RAM+MUX fast enough
+ // reg [31:0] wb_dat_o_reg;
+ // reg stb_d1;
+
+ // always @(posedge wb_clk_i)
+ // begin
+ // wb_dat_o_reg <= buf_doa[which_buf];
+ // stb_d1 <= wb_stb_i;
+ // wb_ack_o <= (stb_d1 & ~wb_ack_o) | (wb_we_i & wb_stb_i);
+ // end
+ //assign wb_dat_o = wb_dat_o_reg;
+
+ mux8 #(.WIDTH(1))
+ mux8_wr0(.en(~write_src[0][3]),.sel(write_src[0][2:0]),
+ .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), .i2(wr_ready_o[2]), .i3(wr_ready_o[3]),
+ .i4(wr_ready_o[4]), .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),
+ .o(wr0_ready_o));
+
+ mux8 #(.WIDTH(1))
+ mux8_wr1(.en(~write_src[1][3]),.sel(write_src[1][2:0]),
+ .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), .i2(wr_ready_o[2]), .i3(wr_ready_o[3]),
+ .i4(wr_ready_o[4]), .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),
+ .o(wr1_ready_o));
+
+ mux8 #(.WIDTH(1))
+ mux8_wr2(.en(~write_src[2][3]),.sel(write_src[2][2:0]),
+ .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), .i2(wr_ready_o[2]), .i3(wr_ready_o[3]),
+ .i4(wr_ready_o[4]), .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),
+ .o(wr2_ready_o));
+
+ mux8 #(.WIDTH(1))
+ mux8_wr3(.en(~write_src[3][3]),.sel(write_src[3][2:0]),
+ .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), .i2(wr_ready_o[2]), .i3(wr_ready_o[3]),
+ .i4(wr_ready_o[4]), .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),
+ .o(wr3_ready_o));
+
+ mux8 #(.WIDTH(37))
+ mux8_rd0(.en(~read_src[0][3]),.sel(read_src[0][2:0]),
+ .i0({rd_data_o[0],rd_flags_o[0],rd_ready_o[0]}),
+ .i1({rd_data_o[1],rd_flags_o[1],rd_ready_o[1]}),
+ .i2({rd_data_o[2],rd_flags_o[2],rd_ready_o[2]}),
+ .i3({rd_data_o[3],rd_flags_o[3],rd_ready_o[3]}),
+ .i4({rd_data_o[4],rd_flags_o[4],rd_ready_o[4]}),
+ .i5({rd_data_o[5],rd_flags_o[5],rd_ready_o[5]}),
+ .i6({rd_data_o[6],rd_flags_o[6],rd_ready_o[6]}),
+ .i7({rd_data_o[7],rd_flags_o[7],rd_ready_o[7]}),
+ .o({rd0_data_o,rd0_flags_o,rd0_ready_o}));
+
+ mux8 #(.WIDTH(37))
+ mux8_rd1(.en(~read_src[1][3]),.sel(read_src[1][2:0]),
+ .i0({rd_data_o[0],rd_flags_o[0],rd_ready_o[0]}),
+ .i1({rd_data_o[1],rd_flags_o[1],rd_ready_o[1]}),
+ .i2({rd_data_o[2],rd_flags_o[2],rd_ready_o[2]}),
+ .i3({rd_data_o[3],rd_flags_o[3],rd_ready_o[3]}),
+ .i4({rd_data_o[4],rd_flags_o[4],rd_ready_o[4]}),
+ .i5({rd_data_o[5],rd_flags_o[5],rd_ready_o[5]}),
+ .i6({rd_data_o[6],rd_flags_o[6],rd_ready_o[6]}),
+ .i7({rd_data_o[7],rd_flags_o[7],rd_ready_o[7]}),
+ .o({rd1_data_o,rd1_flags_o,rd1_ready_o}));
+
+ mux8 #(.WIDTH(37))
+ mux8_rd2(.en(~read_src[2][3]),.sel(read_src[2][2:0]),
+ .i0({rd_data_o[0],rd_flags_o[0],rd_ready_o[0]}),
+ .i1({rd_data_o[1],rd_flags_o[1],rd_ready_o[1]}),
+ .i2({rd_data_o[2],rd_flags_o[2],rd_ready_o[2]}),
+ .i3({rd_data_o[3],rd_flags_o[3],rd_ready_o[3]}),
+ .i4({rd_data_o[4],rd_flags_o[4],rd_ready_o[4]}),
+ .i5({rd_data_o[5],rd_flags_o[5],rd_ready_o[5]}),
+ .i6({rd_data_o[6],rd_flags_o[6],rd_ready_o[6]}),
+ .i7({rd_data_o[7],rd_flags_o[7],rd_ready_o[7]}),
+ .o({rd2_data_o,rd2_flags_o,rd2_ready_o}));
+
+ mux8 #(.WIDTH(37))
+ mux8_rd3(.en(~read_src[3][3]),.sel(read_src[3][2:0]),
+ .i0({rd_data_o[0],rd_flags_o[0],rd_ready_o[0]}),
+ .i1({rd_data_o[1],rd_flags_o[1],rd_ready_o[1]}),
+ .i2({rd_data_o[2],rd_flags_o[2],rd_ready_o[2]}),
+ .i3({rd_data_o[3],rd_flags_o[3],rd_ready_o[3]}),
+ .i4({rd_data_o[4],rd_flags_o[4],rd_ready_o[4]}),
+ .i5({rd_data_o[5],rd_flags_o[5],rd_ready_o[5]}),
+ .i6({rd_data_o[6],rd_flags_o[6],rd_ready_o[6]}),
+ .i7({rd_data_o[7],rd_flags_o[7],rd_ready_o[7]}),
+ .o({rd3_data_o,rd3_flags_o,rd3_ready_o}));
+
+ assign sys_int_o = (|error) | (|done);
+
+endmodule // buffer_pool
diff --git a/fpga/usrp2/control_lib/newfifo/buffer_pool_tb.v b/fpga/usrp2/control_lib/newfifo/buffer_pool_tb.v
new file mode 100644
index 000000000..91a01d268
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/buffer_pool_tb.v
@@ -0,0 +1,58 @@
+
+module buffer_pool_tb();
+
+ wire wb_clk_i;
+ wire wb_rst_i;
+ wire wb_we_i;
+ wire wb_stb_i;
+ wire [15:0] wb_adr_i;
+ wire [31:0] wb_dat_i;
+ wire [31:0] wb_dat_o;
+ wire wb_ack_o;
+ wire wb_err_o;
+ wire wb_rty_o;
+
+ wire stream_clk, stream_rst;
+
+ wire set_stb;
+ wire [7:0] set_addr;
+ wire [31:0] set_data;
+
+ wire [31:0] wr0_data, wr1_data, wr2_data, wr3_data;
+ wire [31:0] rd0_data, rd1_data, rd2_data, rd3_data;
+ wire [3:0] wr0_flags, wr1_flags, wr2_flags, wr3_flags;
+ wire [3:0] rd0_flags, rd1_flags, rd2_flags, rd3_flags;
+ wire wr0_ready, wr1_ready, wr2_ready, wr3_ready;
+ wire rd0_ready, rd1_ready, rd2_ready, rd3_ready;
+ wire wr0_write, wr1_write, wr2_write, wr3_write;
+ wire rd0_read, rd1_read, rd2_read, rd3_read;
+
+ buffer_pool dut
+ (.wb_clk_i(wb_clk_i),
+ .wb_rst_i(wb_rst_i),
+ .wb_we_i(wb_we_i),
+ .wb_stb_i(wb_stb_i),
+ .wb_adr_i(wb_adr_i),
+ .wb_dat_i(wb_dat_i),
+ .wb_dat_o(wb_dat_o),
+ .wb_ack_o(wb_ack_o),
+ .wb_err_o(wb_err_o),
+ .wb_rty_o(wb_rty_o),
+
+ .stream_clk(stream_clk),
+ .stream_rst(stream_rst),
+
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+
+ .wr0_data_i(wr0_data), .wr0_write_i(wr0_write), .wr0_flags_i(wr0_flags), .wr0_ready_o(wr0_ready),
+ .wr1_data_i(wr1_data), .wr1_write_i(wr1_write), .wr1_flags_i(wr1_flags), .wr1_ready_o(wr1_ready),
+ .wr2_data_i(wr2_data), .wr2_write_i(wr2_write), .wr2_flags_i(wr2_flags), .wr2_ready_o(wr2_ready),
+ .wr3_data_i(wr3_data), .wr3_write_i(wr3_write), .wr3_flags_i(wr3_flags), .wr3_ready_o(wr3_ready),
+
+ .rd0_data_o(rd0_data), .rd0_read_i(rd0_read), .rd0_flags_o(rd0_flags), .rd0_ready_o(rd0_ready),
+ .rd1_data_o(rd1_data), .rd1_read_i(rd1_read), .rd1_flags_o(rd1_flags), .rd1_ready_o(rd1_ready),
+ .rd2_data_o(rd2_data), .rd2_read_i(rd2_read), .rd2_flags_o(rd2_flags), .rd2_ready_o(rd2_ready),
+ .rd3_data_o(rd3_data), .rd3_read_i(rd3_read), .rd3_flags_o(rd3_flags), .rd3_ready_o(rd3_ready)
+ );
+
+endmodule // buffer_pool_tb
diff --git a/fpga/usrp2/control_lib/newfifo/fifo19_to_fifo36.v b/fpga/usrp2/control_lib/newfifo/fifo19_to_fifo36.v
new file mode 100644
index 000000000..5f9aeff9b
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo19_to_fifo36.v
@@ -0,0 +1,76 @@
+
+module fifo19_to_fifo36
+ (input clk, input reset, input clear,
+ input [18:0] f19_datain,
+ input f19_src_rdy_i,
+ output f19_dst_rdy_o,
+
+ output [35:0] f36_dataout,
+ output f36_src_rdy_o,
+ input f36_dst_rdy_i,
+ output [31:0] debug
+ );
+
+ reg f36_sof, f36_eof, f36_occ;
+
+ reg [1:0] state;
+ reg [15:0] dat0, dat1;
+
+ wire f19_sof = f19_datain[16];
+ wire f19_eof = f19_datain[17];
+ wire f19_occ = f19_datain[18];
+
+ wire xfer_out = f36_src_rdy_o & f36_dst_rdy_i;
+
+ always @(posedge clk)
+ if(f19_src_rdy_i & ((state==0)|xfer_out))
+ f36_sof <= f19_sof;
+
+ always @(posedge clk)
+ if(f19_src_rdy_i & ((state != 2)|xfer_out))
+ f36_eof <= f19_eof;
+
+ always @(posedge clk) // FIXME check this
+ if(f19_eof)
+ f36_occ <= {state[0],f19_occ};
+ else
+ f36_occ <= 0;
+
+ always @(posedge clk)
+ if(reset)
+ state <= 0;
+ else
+ if(f19_src_rdy_i)
+ case(state)
+ 0 :
+ if(f19_eof)
+ state <= 2;
+ else
+ state <= 1;
+ 1 :
+ state <= 2;
+ 2 :
+ if(xfer_out)
+ if(~f19_eof)
+ state <= 1;
+ // remain in state 2 if we are at eof
+ endcase // case(state)
+ else
+ if(xfer_out)
+ state <= 0;
+
+ always @(posedge clk)
+ if(f19_src_rdy_i & (state==1))
+ dat1 <= f19_datain;
+
+ always @(posedge clk)
+ if(f19_src_rdy_i & ((state==0) | xfer_out))
+ dat0 <= f19_datain;
+
+ assign f19_dst_rdy_o = xfer_out | (state != 2);
+ assign f36_dataout = {f36_occ,f36_eof,f36_sof,dat0,dat1};
+ assign f36_src_rdy_o = (state == 2);
+
+ assign debug = state;
+
+endmodule // fifo19_to_fifo36
diff --git a/fpga/usrp2/control_lib/newfifo/fifo19_to_ll8.v b/fpga/usrp2/control_lib/newfifo/fifo19_to_ll8.v
new file mode 100644
index 000000000..4707f7523
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo19_to_ll8.v
@@ -0,0 +1,53 @@
+
+module fifo19_to_ll8
+ (input clk, input reset, input clear,
+ input [18:0] f19_data,
+ input f19_src_rdy_i,
+ output f19_dst_rdy_o,
+
+ output reg [7:0] ll_data,
+ output ll_sof_n,
+ output ll_eof_n,
+ output ll_src_rdy_n,
+ input ll_dst_rdy_n);
+
+ wire ll_sof, ll_eof, ll_src_rdy;
+ assign ll_sof_n = ~ll_sof;
+ assign ll_eof_n = ~ll_eof;
+ assign ll_src_rdy_n = ~ll_src_rdy;
+ wire ll_dst_rdy = ~ll_dst_rdy_n;
+
+ wire f19_sof = f19_data[16];
+ wire f19_eof = f19_data[17];
+ wire f19_occ = f19_data[18];
+
+ wire advance, end_early;
+ reg state;
+
+ always @(posedge clk)
+ if(reset)
+ state <= 0;
+ else
+ if(advance)
+ if(ll_eof)
+ state <= 0;
+ else
+ state <= state + 1;
+
+ always @*
+ case(state)
+ 0 : ll_data = f19_data[15:8];
+ 1 : ll_data = f19_data[7:0];
+ default : ll_data = f19_data[15:8];
+ endcase // case (state)
+
+ assign ll_sof = (state==0) & f19_sof;
+ assign ll_eof = f19_eof & ((f19_occ==1)|(state==1));
+
+ assign ll_src_rdy = f19_src_rdy_i;
+
+ assign advance = ll_src_rdy & ll_dst_rdy;
+ assign f19_dst_rdy_o = advance & ((state==1)|ll_eof);
+
+endmodule // fifo19_to_ll8
+
diff --git a/fpga/usrp2/control_lib/newfifo/fifo36_to_fifo18.v b/fpga/usrp2/control_lib/newfifo/fifo36_to_fifo18.v
new file mode 100644
index 000000000..b636ab9ca
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo36_to_fifo18.v
@@ -0,0 +1,40 @@
+
+module fifo36_to_fifo18
+ (input clk, input reset, input clear,
+ input [35:0] f36_datain,
+ input f36_src_rdy_i,
+ output f36_dst_rdy_o,
+
+ output [17:0] f18_dataout,
+ output f18_src_rdy_o,
+ input f18_dst_rdy_i );
+
+ wire f36_sof = f36_datain[32];
+ wire f36_eof = f36_datain[33];
+ wire f36_occ = f36_datain[35:34];
+
+ reg phase;
+
+ wire half_line = f36_eof & ((f36_occ==1)|(f36_occ==2));
+
+ assign f18_dataout[15:0] = phase ? f36_datain[15:0] : f36_datain[31:16];
+ assign f18_dataout[16] = phase ? 0 : f36_sof;
+ assign f18_dataout[17] = phase ? f36_eof : half_line;
+
+ assign f18_src_rdy_o = f36_src_rdy_i;
+ assign f36_dst_rdy_o = (phase | half_line) & f18_dst_rdy_i;
+
+ wire f18_xfer = f18_src_rdy_o & f18_dst_rdy_i;
+ wire f36_xfer = f36_src_rdy_i & f36_dst_rdy_o;
+
+ always @(posedge clk)
+ if(reset)
+ phase <= 0;
+ else if(f36_xfer)
+ phase <= 0;
+ else if(f18_xfer)
+ phase <= 1;
+
+
+endmodule // fifo36_to_fifo18
+
diff --git a/fpga/usrp2/control_lib/newfifo/fifo36_to_fifo19.v b/fpga/usrp2/control_lib/newfifo/fifo36_to_fifo19.v
new file mode 100644
index 000000000..de249aaeb
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo36_to_fifo19.v
@@ -0,0 +1,41 @@
+
+module fifo36_to_fifo19
+ (input clk, input reset, input clear,
+ input [35:0] f36_datain,
+ input f36_src_rdy_i,
+ output f36_dst_rdy_o,
+
+ output [18:0] f19_dataout,
+ output f19_src_rdy_o,
+ input f19_dst_rdy_i );
+
+ wire f36_sof = f36_datain[32];
+ wire f36_eof = f36_datain[33];
+ wire f36_occ = f36_datain[35:34];
+
+ reg phase;
+
+ wire half_line = f36_eof & ((f36_occ==1)|(f36_occ==2));
+
+ assign f19_dataout[15:0] = phase ? f36_datain[15:0] : f36_datain[31:16];
+ assign f19_dataout[16] = phase ? 0 : f36_sof;
+ assign f19_dataout[17] = phase ? f36_eof : half_line;
+ assign f19_dataout[18] = f19_dataout[17] & ((f36_occ==1)|(f36_occ==3));
+
+ assign f19_src_rdy_o = f36_src_rdy_i;
+ assign f36_dst_rdy_o = (phase | half_line) & f19_dst_rdy_i;
+
+ wire f19_xfer = f19_src_rdy_o & f19_dst_rdy_i;
+ wire f36_xfer = f36_src_rdy_i & f36_dst_rdy_o;
+
+ always @(posedge clk)
+ if(reset)
+ phase <= 0;
+ else if(f36_xfer)
+ phase <= 0;
+ else if(f19_xfer)
+ phase <= 1;
+
+
+endmodule // fifo36_to_fifo19
+
diff --git a/fpga/usrp2/control_lib/newfifo/fifo36_to_ll8.v b/fpga/usrp2/control_lib/newfifo/fifo36_to_ll8.v
new file mode 100644
index 000000000..0dee1dfc6
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo36_to_ll8.v
@@ -0,0 +1,60 @@
+
+module fifo36_to_ll8
+ (input clk, input reset, input clear,
+ input [35:0] f36_data,
+ input f36_src_rdy_i,
+ output f36_dst_rdy_o,
+
+ output reg [7:0] ll_data,
+ output ll_sof_n,
+ output ll_eof_n,
+ output ll_src_rdy_n,
+ input ll_dst_rdy_n,
+
+ output [31:0] debug);
+
+ wire ll_sof, ll_eof, ll_src_rdy;
+ assign ll_sof_n = ~ll_sof;
+ assign ll_eof_n = ~ll_eof;
+ assign ll_src_rdy_n = ~ll_src_rdy;
+ wire ll_dst_rdy = ~ll_dst_rdy_n;
+
+ wire f36_sof = f36_data[32];
+ wire f36_eof = f36_data[33];
+ wire f36_occ = f36_data[35:34];
+ wire advance, end_early;
+ reg [1:0] state;
+ assign debug = {29'b0,state};
+
+ always @(posedge clk)
+ if(reset)
+ state <= 0;
+ else
+ if(advance)
+ if(ll_eof)
+ state <= 0;
+ else
+ state <= state + 1;
+
+ always @*
+ case(state)
+ 0 : ll_data = f36_data[31:24];
+ 1 : ll_data = f36_data[23:16];
+ 2 : ll_data = f36_data[15:8];
+ 3 : ll_data = f36_data[7:0];
+ default : ll_data = f36_data[31:24];
+ endcase // case (state)
+
+ assign ll_sof = (state==0) & f36_sof;
+ assign ll_eof = f36_eof & (((state==0)&(f36_occ==1)) |
+ ((state==1)&(f36_occ==2)) |
+ ((state==2)&(f36_occ==3)) |
+ (state==3));
+
+ assign ll_src_rdy = f36_src_rdy_i;
+
+ assign advance = ll_src_rdy & ll_dst_rdy;
+ assign f36_dst_rdy_o = advance & ((state==3)|ll_eof);
+ assign debug = state;
+
+endmodule // ll8_to_fifo36
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_2clock.v b/fpga/usrp2/control_lib/newfifo/fifo_2clock.v
new file mode 100644
index 000000000..34c85ccb4
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo_2clock.v
@@ -0,0 +1,117 @@
+
+// FIXME ignores the AWIDTH (fifo size) parameter
+
+module fifo_2clock
+ #(parameter WIDTH=36, SIZE=6)
+ (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 arst);
+
+ wire [SIZE:0] level_rclk, level_wclk; // xilinx adds an extra bit if you ask for accurate levels
+ wire full, empty, write, read;
+
+ assign dst_rdy_o = ~full;
+ assign src_rdy_o = ~empty;
+ assign write = src_rdy_i & dst_rdy_o;
+ assign read = src_rdy_o & dst_rdy_i;
+
+ generate
+ if(WIDTH==36)
+ if(SIZE==9)
+ fifo_xlnx_512x36_2clk fifo_xlnx_512x36_2clk
+ (.rst(arst),
+ .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
+ .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
+ else if(SIZE==11)
+ fifo_xlnx_2Kx36_2clk fifo_xlnx_2Kx36_2clk
+ (.rst(arst),
+ .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
+ .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
+ else if(SIZE==6)
+ fifo_xlnx_64x36_2clk fifo_xlnx_64x36_2clk
+ (.rst(arst),
+ .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
+ .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
+ else
+ fifo_xlnx_512x36_2clk fifo_xlnx_512x36_2clk
+ (.rst(arst),
+ .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
+ .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
+ else if((WIDTH==19)|(WIDTH==18))
+ if(SIZE==4)
+ fifo_xlnx_16x19_2clk fifo_xlnx_16x19_2clk
+ (.rst(arst),
+ .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
+ .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
+ endgenerate
+
+ assign occupied = {{(16-SIZE-1){1'b0}},level_rclk};
+ assign space = ((1<<SIZE)+1)-level_wclk;
+
+endmodule // fifo_2clock
+
+/*
+`else
+ // ISE sucks, so the following doesn't work properly
+
+ reg [AWIDTH-1:0] wr_addr, rd_addr;
+ wire [AWIDTH-1:0] wr_addr_rclk, rd_addr_wclk;
+ wire [AWIDTH-1:0] next_rd_addr;
+ wire enb_read;
+
+ // Write side management
+ wire [AWIDTH-1:0] next_wr_addr = wr_addr + 1;
+ always @(posedge wclk or posedge arst)
+ if(arst)
+ wr_addr <= 0;
+ else if(write)
+ wr_addr <= next_wr_addr;
+ assign full = (next_wr_addr == rd_addr_wclk);
+
+ // RAM for data storage. Data out is registered, complicating the
+ // read side logic
+ ram_2port #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) mac_rx_ff_ram
+ (.clka(wclk),.ena(1'b1),.wea(write),.addra(wr_addr),.dia(datain),.doa(),
+ .clkb(rclk),.enb(enb_read),.web(1'b0),.addrb(next_rd_addr),.dib(0),.dob(dataout) );
+
+ // Read side management
+ reg data_valid;
+ assign empty = ~data_valid;
+ assign next_rd_addr = rd_addr + data_valid;
+ assign enb_read = read | ~data_valid;
+
+ always @(posedge rclk or posedge arst)
+ if(arst)
+ rd_addr <= 0;
+ else if(read)
+ rd_addr <= rd_addr + 1;
+
+ always @(posedge rclk or posedge arst)
+ if(arst)
+ data_valid <= 0;
+ else
+ if(read & (next_rd_addr == wr_addr_rclk))
+ data_valid <= 0;
+ else if(next_rd_addr != wr_addr_rclk)
+ data_valid <= 1;
+
+ // Send pointers across clock domains via gray code
+ gray_send #(.WIDTH(AWIDTH)) send_wr_addr
+ (.clk_in(wclk),.addr_in(wr_addr),
+ .clk_out(rclk),.addr_out(wr_addr_rclk) );
+
+ gray_send #(.WIDTH(AWIDTH)) send_rd_addr
+ (.clk_in(rclk),.addr_in(rd_addr),
+ .clk_out(wclk),.addr_out(rd_addr_wclk) );
+
+ // Generate fullness info, these are approximate and may be delayed
+ // and are only for higher-level flow control.
+ // Only full and empty are guaranteed exact.
+ always @(posedge wclk)
+ level_wclk <= wr_addr - rd_addr_wclk;
+ always @(posedge rclk)
+ level_rclk <= wr_addr_rclk - rd_addr;
+`endif
+endmodule // fifo_2clock
+
+*/
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_2clock_cascade.v b/fpga/usrp2/control_lib/newfifo/fifo_2clock_cascade.v
new file mode 100644
index 000000000..5ce726977
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo_2clock_cascade.v
@@ -0,0 +1,35 @@
+
+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 arst);
+
+ wire [WIDTH-1:0] data_int1, data_int2;
+ wire src_rdy_int1, src_rdy_int2, dst_rdy_int1, dst_rdy_int2;
+ wire [SIZE-1:0] level_wclk, level_rclk;
+ wire [4:0] s1_space, s1_occupied, s2_space, s2_occupied;
+ wire [15:0] l_space, l_occupied;
+
+ fifo_short #(.WIDTH(WIDTH)) shortfifo
+ (.clk(wclk), .reset(arst), .clear(0),
+ .datain(datain), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o),
+ .dataout(data_int1), .src_rdy_o(src_rdy_int1), .dst_rdy_i(dst_rdy_int1),
+ .space(s1_space), .occupied(s1_occupied) );
+
+ fifo_2clock #(.WIDTH(WIDTH),.SIZE(SIZE)) fifo_2clock
+ (.wclk(wclk), .datain(data_int1), .src_rdy_i(src_rdy_int1), .dst_rdy_o(dst_rdy_int1), .space(l_space),
+ .rclk(rclk), .dataout(data_int2), .src_rdy_o(src_rdy_int2), .dst_rdy_i(dst_rdy_int2), .occupied(l_occupied),
+ .arst(arst) );
+
+ fifo_short #(.WIDTH(WIDTH)) shortfifo2
+ (.clk(rclk), .reset(arst), .clear(0),
+ .datain(data_int2), .src_rdy_i(src_rdy_int2), .dst_rdy_o(dst_rdy_int2),
+ .dataout(dataout), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i),
+ .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;
+
+endmodule // fifo_2clock_cascade
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_cascade.v b/fpga/usrp2/control_lib/newfifo/fifo_cascade.v
new file mode 100644
index 000000000..fdd8449bc
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo_cascade.v
@@ -0,0 +1,52 @@
+
+
+// This FIFO exists to provide an intermediate point for the data on its
+// long trek from one RAM (in the buffer pool) to another (in the longfifo)
+// The shortfifo is more flexible in its placement since it is based on
+// distributed RAM
+
+// This one has the shortfifo on both the in and out sides.
+module fifo_cascade
+ #(parameter WIDTH=32, SIZE=9)
+ (input clk, input reset, input clear,
+ input [WIDTH-1:0] datain,
+ input src_rdy_i,
+ output dst_rdy_o,
+ output [WIDTH-1:0] dataout,
+ output src_rdy_o,
+ input dst_rdy_i,
+ output [15:0] space,
+ output [15:0] occupied);
+
+ wire [WIDTH-1:0] data_int, data_int2;
+ wire src_rdy_1, dst_rdy_1, src_rdy_2, dst_rdy_2;
+
+ wire [4:0] s1_space, s1_occupied, s2_space, s2_occupied;
+ wire [15:0] l_space, l_occupied;
+
+ fifo_short #(.WIDTH(WIDTH)) head_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(datain), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o),
+ .dataout(data_int), .src_rdy_o(src_rdy_1), .dst_rdy_i(dst_rdy_1),
+ .space(s1_space),.occupied(s1_occupied) );
+
+ fifo_long #(.WIDTH(WIDTH),.SIZE(SIZE)) middle_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(data_int), .src_rdy_i(src_rdy_1), .dst_rdy_o(dst_rdy_1),
+ .dataout(data_int2), .src_rdy_o(src_rdy_2), .dst_rdy_i(dst_rdy_2),
+ .space(l_space),.occupied(l_occupied) );
+
+ fifo_short #(.WIDTH(WIDTH)) tail_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(data_int2), .src_rdy_i(src_rdy_2), .dst_rdy_o(dst_rdy_2),
+ .dataout(dataout), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i),
+ .space(s2_space),.occupied(s2_occupied) );
+
+ assign space = {11'b0,s1_space} + {11'b0,s2_space} + l_space;
+ assign occupied = {11'b0,s1_occupied} + {11'b0,s2_occupied} + l_occupied;
+
+endmodule // cascadefifo2
+
+
+
+
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_long.v b/fpga/usrp2/control_lib/newfifo/fifo_long.v
new file mode 100644
index 000000000..0426779f6
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo_long.v
@@ -0,0 +1,148 @@
+
+// FIFO intended to be interchangeable with shortfifo, but
+// based on block ram instead of SRL16's
+// only one clock domain
+
+// Port A is write port, Port B is read port
+
+module fifo_long
+ #(parameter WIDTH=32, SIZE=9)
+ (input clk, input reset, input clear,
+ input [WIDTH-1:0] datain,
+ input src_rdy_i,
+ output dst_rdy_o,
+ output [WIDTH-1:0] dataout,
+ output src_rdy_o,
+ input dst_rdy_i,
+
+ output reg [15:0] space,
+ output reg [15:0] occupied);
+
+ wire write = src_rdy_i & dst_rdy_o;
+ wire read = dst_rdy_i & src_rdy_o;
+ wire full, empty;
+
+ assign dst_rdy_o = ~full;
+ assign src_rdy_o = ~empty;
+
+ // Read side states
+ localparam EMPTY = 0;
+ localparam PRE_READ = 1;
+ localparam READING = 2;
+
+ reg [SIZE-1:0] wr_addr, rd_addr;
+ reg [1:0] read_state;
+
+ reg empty_reg, full_reg;
+ always @(posedge clk)
+ if(reset)
+ wr_addr <= 0;
+ else if(clear)
+ wr_addr <= 0;
+ else if(write)
+ wr_addr <= wr_addr + 1;
+
+ ram_2port #(.DWIDTH(WIDTH),.AWIDTH(SIZE))
+ ram (.clka(clk),
+ .ena(1'b1),
+ .wea(write),
+ .addra(wr_addr),
+ .dia(datain),
+ .doa(),
+
+ .clkb(clk),
+ .enb((read_state==PRE_READ)|read),
+ .web(0),
+ .addrb(rd_addr),
+ .dib(0),
+ .dob(dataout));
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ read_state <= EMPTY;
+ rd_addr <= 0;
+ empty_reg <= 1;
+ end
+ else
+ if(clear)
+ begin
+ read_state <= EMPTY;
+ rd_addr <= 0;
+ empty_reg <= 1;
+ end
+ else
+ case(read_state)
+ EMPTY :
+ if(write)
+ begin
+ //rd_addr <= wr_addr;
+ read_state <= PRE_READ;
+ end
+ PRE_READ :
+ begin
+ read_state <= READING;
+ empty_reg <= 0;
+ rd_addr <= rd_addr + 1;
+ end
+
+ READING :
+ if(read)
+ if(rd_addr == wr_addr)
+ begin
+ empty_reg <= 1;
+ if(write)
+ read_state <= PRE_READ;
+ else
+ read_state <= EMPTY;
+ end
+ else
+ rd_addr <= rd_addr + 1;
+ endcase // case(read_state)
+
+ wire [SIZE-1:0] dont_write_past_me = rd_addr - 3;
+ wire becoming_full = wr_addr == dont_write_past_me;
+
+ always @(posedge clk)
+ if(reset)
+ full_reg <= 0;
+ else if(clear)
+ full_reg <= 0;
+ else if(read & ~write)
+ full_reg <= 0;
+ //else if(write & ~read & (wr_addr == (rd_addr-3)))
+ else if(write & ~read & becoming_full)
+ full_reg <= 1;
+
+ //assign empty = (read_state != READING);
+ assign empty = empty_reg;
+
+ // assign full = ((rd_addr - 1) == wr_addr);
+ assign full = full_reg;
+
+ //////////////////////////////////////////////
+ // space and occupied are for diagnostics only
+ // not guaranteed exact
+
+ localparam NUMLINES = (1<<SIZE)-2;
+ always @(posedge clk)
+ if(reset)
+ space <= NUMLINES;
+ else if(clear)
+ space <= NUMLINES;
+ else if(read & ~write)
+ space <= space + 1;
+ else if(write & ~read)
+ space <= space - 1;
+
+ always @(posedge clk)
+ if(reset)
+ occupied <= 0;
+ else if(clear)
+ occupied <= 0;
+ else if(read & ~write)
+ occupied <= occupied - 1;
+ else if(write & ~read)
+ occupied <= occupied + 1;
+
+endmodule // fifo_long
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_new_tb.vcd b/fpga/usrp2/control_lib/newfifo/fifo_new_tb.vcd
new file mode 100644
index 000000000..796889e7d
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo_new_tb.vcd
@@ -0,0 +1,5506 @@
+$date
+ Thu Mar 19 17:21:11 2009
+$end
+$version
+ Icarus Verilog
+$end
+$timescale
+ 1ps
+$end
+$scope module fifo_new_tb $end
+$var wire 1 ! dst_rdy_f36i $end
+$var wire 36 " f36_in [35:0] $end
+$var wire 36 # i1 [35:0] $end
+$var wire 1 $ i1_dr $end
+$var wire 1 % i1_sr $end
+$var wire 19 & i2 [18:0] $end
+$var wire 1 ' i2_dr $end
+$var wire 1 ( i2_sr $end
+$var wire 19 ) i3 [18:0] $end
+$var wire 1 * i3_dr $end
+$var wire 1 + i3_sr $end
+$var wire 36 , i4 [35:0] $end
+$var wire 1 - i4_sr $end
+$var wire 8 . ll_data [7:0] $end
+$var wire 1 / ll_dst_rdy_n $end
+$var wire 1 0 ll_eof_n $end
+$var wire 1 1 ll_sof_n $end
+$var wire 1 2 ll_src_rdy_n $end
+$var reg 1 3 clear $end
+$var reg 1 4 clk $end
+$var reg 16 5 count [15:0] $end
+$var reg 1 6 dst_rdy_f36o $end
+$var reg 32 7 f36_data [31:0] $end
+$var reg 1 8 f36_eof $end
+$var reg 2 9 f36_occ [1:0] $end
+$var reg 1 : f36_sof $end
+$var reg 1 ; i4_dr $end
+$var reg 1 < rst $end
+$var reg 1 = src_rdy_f36i $end
+$scope module fifo_short1 $end
+$var wire 1 > clear $end
+$var wire 1 ? clk $end
+$var wire 36 @ datain [35:0] $end
+$var wire 36 A dataout [35:0] $end
+$var wire 1 $ dst_rdy_i $end
+$var wire 1 ! dst_rdy_o $end
+$var wire 1 B read $end
+$var wire 1 C reset $end
+$var wire 1 D src_rdy_i $end
+$var wire 1 % src_rdy_o $end
+$var wire 1 E write $end
+$var reg 4 F a [3:0] $end
+$var reg 1 G empty $end
+$var reg 1 H full $end
+$var reg 5 I occupied [4:0] $end
+$var reg 5 J space [4:0] $end
+$scope begin gen_srl16[0] $end
+$scope module srl16e $end
+$var wire 1 K A0 $end
+$var wire 1 L A1 $end
+$var wire 1 M A2 $end
+$var wire 1 N A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 O D $end
+$var wire 1 P Q $end
+$var reg 16 Q data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[1] $end
+$scope module srl16e $end
+$var wire 1 R A0 $end
+$var wire 1 S A1 $end
+$var wire 1 T A2 $end
+$var wire 1 U A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 V D $end
+$var wire 1 W Q $end
+$var reg 16 X data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[2] $end
+$scope module srl16e $end
+$var wire 1 Y A0 $end
+$var wire 1 Z A1 $end
+$var wire 1 [ A2 $end
+$var wire 1 \ A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 ] D $end
+$var wire 1 ^ Q $end
+$var reg 16 _ data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[3] $end
+$scope module srl16e $end
+$var wire 1 ` A0 $end
+$var wire 1 a A1 $end
+$var wire 1 b A2 $end
+$var wire 1 c A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 d D $end
+$var wire 1 e Q $end
+$var reg 16 f data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[4] $end
+$scope module srl16e $end
+$var wire 1 g A0 $end
+$var wire 1 h A1 $end
+$var wire 1 i A2 $end
+$var wire 1 j A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 k D $end
+$var wire 1 l Q $end
+$var reg 16 m data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[5] $end
+$scope module srl16e $end
+$var wire 1 n A0 $end
+$var wire 1 o A1 $end
+$var wire 1 p A2 $end
+$var wire 1 q A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 r D $end
+$var wire 1 s Q $end
+$var reg 16 t data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[6] $end
+$scope module srl16e $end
+$var wire 1 u A0 $end
+$var wire 1 v A1 $end
+$var wire 1 w A2 $end
+$var wire 1 x A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 y D $end
+$var wire 1 z Q $end
+$var reg 16 { data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[7] $end
+$scope module srl16e $end
+$var wire 1 | A0 $end
+$var wire 1 } A1 $end
+$var wire 1 ~ A2 $end
+$var wire 1 !" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 "" D $end
+$var wire 1 #" Q $end
+$var reg 16 $" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[8] $end
+$scope module srl16e $end
+$var wire 1 %" A0 $end
+$var wire 1 &" A1 $end
+$var wire 1 '" A2 $end
+$var wire 1 (" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 )" D $end
+$var wire 1 *" Q $end
+$var reg 16 +" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[9] $end
+$scope module srl16e $end
+$var wire 1 ," A0 $end
+$var wire 1 -" A1 $end
+$var wire 1 ." A2 $end
+$var wire 1 /" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 0" D $end
+$var wire 1 1" Q $end
+$var reg 16 2" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[10] $end
+$scope module srl16e $end
+$var wire 1 3" A0 $end
+$var wire 1 4" A1 $end
+$var wire 1 5" A2 $end
+$var wire 1 6" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 7" D $end
+$var wire 1 8" Q $end
+$var reg 16 9" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[11] $end
+$scope module srl16e $end
+$var wire 1 :" A0 $end
+$var wire 1 ;" A1 $end
+$var wire 1 <" A2 $end
+$var wire 1 =" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 >" D $end
+$var wire 1 ?" Q $end
+$var reg 16 @" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[12] $end
+$scope module srl16e $end
+$var wire 1 A" A0 $end
+$var wire 1 B" A1 $end
+$var wire 1 C" A2 $end
+$var wire 1 D" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 E" D $end
+$var wire 1 F" Q $end
+$var reg 16 G" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[13] $end
+$scope module srl16e $end
+$var wire 1 H" A0 $end
+$var wire 1 I" A1 $end
+$var wire 1 J" A2 $end
+$var wire 1 K" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 L" D $end
+$var wire 1 M" Q $end
+$var reg 16 N" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[14] $end
+$scope module srl16e $end
+$var wire 1 O" A0 $end
+$var wire 1 P" A1 $end
+$var wire 1 Q" A2 $end
+$var wire 1 R" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 S" D $end
+$var wire 1 T" Q $end
+$var reg 16 U" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[15] $end
+$scope module srl16e $end
+$var wire 1 V" A0 $end
+$var wire 1 W" A1 $end
+$var wire 1 X" A2 $end
+$var wire 1 Y" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 Z" D $end
+$var wire 1 [" Q $end
+$var reg 16 \" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[16] $end
+$scope module srl16e $end
+$var wire 1 ]" A0 $end
+$var wire 1 ^" A1 $end
+$var wire 1 _" A2 $end
+$var wire 1 `" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 a" D $end
+$var wire 1 b" Q $end
+$var reg 16 c" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[17] $end
+$scope module srl16e $end
+$var wire 1 d" A0 $end
+$var wire 1 e" A1 $end
+$var wire 1 f" A2 $end
+$var wire 1 g" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 h" D $end
+$var wire 1 i" Q $end
+$var reg 16 j" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[18] $end
+$scope module srl16e $end
+$var wire 1 k" A0 $end
+$var wire 1 l" A1 $end
+$var wire 1 m" A2 $end
+$var wire 1 n" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 o" D $end
+$var wire 1 p" Q $end
+$var reg 16 q" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[19] $end
+$scope module srl16e $end
+$var wire 1 r" A0 $end
+$var wire 1 s" A1 $end
+$var wire 1 t" A2 $end
+$var wire 1 u" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 v" D $end
+$var wire 1 w" Q $end
+$var reg 16 x" data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[20] $end
+$scope module srl16e $end
+$var wire 1 y" A0 $end
+$var wire 1 z" A1 $end
+$var wire 1 {" A2 $end
+$var wire 1 |" A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 }" D $end
+$var wire 1 ~" Q $end
+$var reg 16 !# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[21] $end
+$scope module srl16e $end
+$var wire 1 "# A0 $end
+$var wire 1 ## A1 $end
+$var wire 1 $# A2 $end
+$var wire 1 %# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 &# D $end
+$var wire 1 '# Q $end
+$var reg 16 (# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[22] $end
+$scope module srl16e $end
+$var wire 1 )# A0 $end
+$var wire 1 *# A1 $end
+$var wire 1 +# A2 $end
+$var wire 1 ,# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 -# D $end
+$var wire 1 .# Q $end
+$var reg 16 /# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[23] $end
+$scope module srl16e $end
+$var wire 1 0# A0 $end
+$var wire 1 1# A1 $end
+$var wire 1 2# A2 $end
+$var wire 1 3# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 4# D $end
+$var wire 1 5# Q $end
+$var reg 16 6# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[24] $end
+$scope module srl16e $end
+$var wire 1 7# A0 $end
+$var wire 1 8# A1 $end
+$var wire 1 9# A2 $end
+$var wire 1 :# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 ;# D $end
+$var wire 1 <# Q $end
+$var reg 16 =# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[25] $end
+$scope module srl16e $end
+$var wire 1 ># A0 $end
+$var wire 1 ?# A1 $end
+$var wire 1 @# A2 $end
+$var wire 1 A# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 B# D $end
+$var wire 1 C# Q $end
+$var reg 16 D# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[26] $end
+$scope module srl16e $end
+$var wire 1 E# A0 $end
+$var wire 1 F# A1 $end
+$var wire 1 G# A2 $end
+$var wire 1 H# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 I# D $end
+$var wire 1 J# Q $end
+$var reg 16 K# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[27] $end
+$scope module srl16e $end
+$var wire 1 L# A0 $end
+$var wire 1 M# A1 $end
+$var wire 1 N# A2 $end
+$var wire 1 O# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 P# D $end
+$var wire 1 Q# Q $end
+$var reg 16 R# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[28] $end
+$scope module srl16e $end
+$var wire 1 S# A0 $end
+$var wire 1 T# A1 $end
+$var wire 1 U# A2 $end
+$var wire 1 V# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 W# D $end
+$var wire 1 X# Q $end
+$var reg 16 Y# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[29] $end
+$scope module srl16e $end
+$var wire 1 Z# A0 $end
+$var wire 1 [# A1 $end
+$var wire 1 \# A2 $end
+$var wire 1 ]# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 ^# D $end
+$var wire 1 _# Q $end
+$var reg 16 `# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[30] $end
+$scope module srl16e $end
+$var wire 1 a# A0 $end
+$var wire 1 b# A1 $end
+$var wire 1 c# A2 $end
+$var wire 1 d# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 e# D $end
+$var wire 1 f# Q $end
+$var reg 16 g# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[31] $end
+$scope module srl16e $end
+$var wire 1 h# A0 $end
+$var wire 1 i# A1 $end
+$var wire 1 j# A2 $end
+$var wire 1 k# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 l# D $end
+$var wire 1 m# Q $end
+$var reg 16 n# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[32] $end
+$scope module srl16e $end
+$var wire 1 o# A0 $end
+$var wire 1 p# A1 $end
+$var wire 1 q# A2 $end
+$var wire 1 r# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 s# D $end
+$var wire 1 t# Q $end
+$var reg 16 u# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[33] $end
+$scope module srl16e $end
+$var wire 1 v# A0 $end
+$var wire 1 w# A1 $end
+$var wire 1 x# A2 $end
+$var wire 1 y# A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 z# D $end
+$var wire 1 {# Q $end
+$var reg 16 |# data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[34] $end
+$scope module srl16e $end
+$var wire 1 }# A0 $end
+$var wire 1 ~# A1 $end
+$var wire 1 !$ A2 $end
+$var wire 1 "$ A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 #$ D $end
+$var wire 1 $$ Q $end
+$var reg 16 %$ data [15:0] $end
+$upscope $end
+$upscope $end
+$scope begin gen_srl16[35] $end
+$scope module srl16e $end
+$var wire 1 &$ A0 $end
+$var wire 1 '$ A1 $end
+$var wire 1 ($ A2 $end
+$var wire 1 )$ A3 $end
+$var wire 1 E CE $end
+$var wire 1 ? CLK $end
+$var wire 1 *$ D $end
+$var wire 1 +$ Q $end
+$var reg 16 ,$ data [15:0] $end
+$upscope $end
+$upscope $end
+$upscope $end
+$scope module fifo36_to_fifo19 $end
+$var wire 1 > clear $end
+$var wire 1 ? clk $end
+$var wire 19 -$ f19_dataout [18:0] $end
+$var wire 1 ' f19_dst_rdy_i $end
+$var wire 1 ( f19_src_rdy_o $end
+$var wire 1 .$ f19_xfer $end
+$var wire 36 /$ f36_datain [35:0] $end
+$var wire 1 $ f36_dst_rdy_o $end
+$var wire 1 0$ f36_eof $end
+$var wire 1 1$ f36_occ $end
+$var wire 1 2$ f36_sof $end
+$var wire 1 % f36_src_rdy_i $end
+$var wire 1 3$ f36_xfer $end
+$var wire 1 4$ half_line $end
+$var wire 1 C reset $end
+$var reg 1 5$ phase $end
+$upscope $end
+$scope module fifo19_to_ll8 $end
+$var wire 1 6$ advance $end
+$var wire 1 > clear $end
+$var wire 1 ? clk $end
+$var wire 19 7$ f19_data [18:0] $end
+$var wire 1 ' f19_dst_rdy_o $end
+$var wire 1 8$ f19_eof $end
+$var wire 1 9$ f19_occ $end
+$var wire 1 :$ f19_sof $end
+$var wire 1 ( f19_src_rdy_i $end
+$var wire 1 ;$ ll_dst_rdy $end
+$var wire 1 / ll_dst_rdy_n $end
+$var wire 1 <$ ll_eof $end
+$var wire 1 0 ll_eof_n $end
+$var wire 1 =$ ll_sof $end
+$var wire 1 1 ll_sof_n $end
+$var wire 1 >$ ll_src_rdy $end
+$var wire 1 2 ll_src_rdy_n $end
+$var wire 1 C reset $end
+$var reg 8 ?$ ll_data [7:0] $end
+$var reg 1 @$ state $end
+$upscope $end
+$scope module ll8_to_fifo19 $end
+$var wire 1 > clear $end
+$var wire 1 ? clk $end
+$var wire 19 A$ f19_data [18:0] $end
+$var wire 1 * f19_dst_rdy_i $end
+$var wire 1 + f19_src_rdy_o $end
+$var wire 8 B$ ll_data [7:0] $end
+$var wire 1 C$ ll_dst_rdy $end
+$var wire 1 / ll_dst_rdy_n $end
+$var wire 1 D$ ll_eof $end
+$var wire 1 0 ll_eof_n $end
+$var wire 1 E$ ll_sof $end
+$var wire 1 1 ll_sof_n $end
+$var wire 1 F$ ll_src_rdy $end
+$var wire 1 2 ll_src_rdy_n $end
+$var wire 1 C reset $end
+$var wire 1 G$ xfer_out $end
+$var reg 8 H$ dat0 [7:0] $end
+$var reg 8 I$ dat1 [7:0] $end
+$var reg 1 J$ f19_eof $end
+$var reg 1 K$ f19_occ $end
+$var reg 1 L$ f19_sof $end
+$var reg 2 M$ state [1:0] $end
+$upscope $end
+$scope module fifo19_to_fifo36 $end
+$var wire 1 > clear $end
+$var wire 1 ? clk $end
+$var wire 19 N$ f19_datain [18:0] $end
+$var wire 1 * f19_dst_rdy_o $end
+$var wire 1 O$ f19_eof $end
+$var wire 1 P$ f19_occ $end
+$var wire 1 Q$ f19_sof $end
+$var wire 1 + f19_src_rdy_i $end
+$var wire 36 R$ f36_dataout [35:0] $end
+$var wire 1 S$ f36_dst_rdy_i $end
+$var wire 1 - f36_src_rdy_o $end
+$var wire 1 C reset $end
+$var wire 1 T$ xfer_out $end
+$var reg 16 U$ dat0 [15:0] $end
+$var reg 16 V$ dat1 [15:0] $end
+$var reg 1 W$ f36_eof $end
+$var reg 1 X$ f36_occ $end
+$var reg 1 Y$ f36_sof $end
+$var reg 2 Z$ state [1:0] $end
+$upscope $end
+$scope task PutPacketInFIFO36 $end
+$var reg 32 [$ data_len [31:0] $end
+$var reg 32 \$ data_start [31:0] $end
+$upscope $end
+$scope task ReadFromFIFO36 $end
+$upscope $end
+$upscope $end
+$enddefinitions $end
+#0
+$dumpvars
+bx \$
+bx [$
+bx Z$
+xY$
+xX$
+xW$
+bx V$
+bx U$
+0T$
+0S$
+b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx R$
+xQ$
+xP$
+xO$
+bx N$
+bx M$
+xL$
+xK$
+xJ$
+bx I$
+bx H$
+xG$
+xF$
+xE$
+xD$
+xC$
+bx B$
+bx A$
+x@$
+bx ?$
+x>$
+x=$
+x<$
+x;$
+x:$
+x9$
+x8$
+bx 7$
+x6$
+x5$
+x4$
+x3$
+x2$
+x1$
+x0$
+bx /$
+x.$
+bx -$
+b0 ,$
+x+$
+0*$
+x)$
+x($
+x'$
+x&$
+b0 %$
+x$$
+0#$
+x"$
+x!$
+x~#
+x}#
+b0 |#
+x{#
+0z#
+xy#
+xx#
+xw#
+xv#
+b0 u#
+xt#
+0s#
+xr#
+xq#
+xp#
+xo#
+b0 n#
+xm#
+0l#
+xk#
+xj#
+xi#
+xh#
+b0 g#
+xf#
+0e#
+xd#
+xc#
+xb#
+xa#
+b0 `#
+x_#
+0^#
+x]#
+x\#
+x[#
+xZ#
+b0 Y#
+xX#
+0W#
+xV#
+xU#
+xT#
+xS#
+b0 R#
+xQ#
+0P#
+xO#
+xN#
+xM#
+xL#
+b0 K#
+xJ#
+0I#
+xH#
+xG#
+xF#
+xE#
+b0 D#
+xC#
+0B#
+xA#
+x@#
+x?#
+x>#
+b0 =#
+x<#
+0;#
+x:#
+x9#
+x8#
+x7#
+b0 6#
+x5#
+04#
+x3#
+x2#
+x1#
+x0#
+b0 /#
+x.#
+0-#
+x,#
+x+#
+x*#
+x)#
+b0 (#
+x'#
+0&#
+x%#
+x$#
+x##
+x"#
+b0 !#
+x~"
+0}"
+x|"
+x{"
+xz"
+xy"
+b0 x"
+xw"
+0v"
+xu"
+xt"
+xs"
+xr"
+b0 q"
+xp"
+0o"
+xn"
+xm"
+xl"
+xk"
+b0 j"
+xi"
+0h"
+xg"
+xf"
+xe"
+xd"
+b0 c"
+xb"
+0a"
+x`"
+x_"
+x^"
+x]"
+b0 \"
+x["
+0Z"
+xY"
+xX"
+xW"
+xV"
+b0 U"
+xT"
+0S"
+xR"
+xQ"
+xP"
+xO"
+b0 N"
+xM"
+0L"
+xK"
+xJ"
+xI"
+xH"
+b0 G"
+xF"
+0E"
+xD"
+xC"
+xB"
+xA"
+b0 @"
+x?"
+0>"
+x="
+x<"
+x;"
+x:"
+b0 9"
+x8"
+07"
+x6"
+x5"
+x4"
+x3"
+b0 2"
+x1"
+00"
+x/"
+x."
+x-"
+x,"
+b0 +"
+x*"
+0)"
+x("
+x'"
+x&"
+x%"
+b0 $"
+x#"
+0""
+x!"
+x~
+x}
+x|
+b0 {
+xz
+0y
+xx
+xw
+xv
+xu
+b0 t
+xs
+0r
+xq
+xp
+xo
+xn
+b0 m
+xl
+0k
+xj
+xi
+xh
+xg
+b0 f
+xe
+0d
+xc
+xb
+xa
+x`
+b0 _
+x^
+0]
+x\
+x[
+xZ
+xY
+b0 X
+xW
+0V
+xU
+xT
+xS
+xR
+b0 Q
+xP
+0O
+xN
+xM
+xL
+xK
+bx J
+bx I
+xH
+xG
+bx F
+0E
+0D
+1C
+xB
+bx A
+b0 @
+0?
+0>
+0=
+1<
+0;
+0:
+b0 9
+08
+b0 7
+06
+bx 5
+04
+03
+x2
+x1
+x0
+x/
+bx .
+x-
+b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ,
+x+
+x*
+bx )
+x(
+x'
+bx &
+x%
+x$
+bx #
+b0 "
+x!
+$end
+#50000000000000
+0D$
+10
+0E$
+0<$
+11
+08$
+09$
+0=$
+0$
+b0 ?$
+b0 .
+b0 B$
+0:$
+0'
+0F$
+04$
+01$
+b0 &
+b0 -$
+b0 7$
+1;$
+0.$
+06$
+12
+03$
+0B
+02$
+00$
+0/
+1!
+0>$
+0(
+0%
+0K
+0P
+0L
+0M
+0N
+0R
+0W
+0S
+0T
+0U
+0Y
+0^
+0Z
+0[
+0\
+0`
+0e
+0a
+0b
+0c
+0g
+0l
+0h
+0i
+0j
+0n
+0s
+0o
+0p
+0q
+0u
+0z
+0v
+0w
+0x
+0|
+0#"
+0}
+0~
+0!"
+0%"
+0*"
+0&"
+0'"
+0("
+0,"
+01"
+0-"
+0."
+0/"
+03"
+08"
+04"
+05"
+06"
+0:"
+0?"
+0;"
+0<"
+0="
+0A"
+0F"
+0B"
+0C"
+0D"
+0H"
+0M"
+0I"
+0J"
+0K"
+0O"
+0T"
+0P"
+0Q"
+0R"
+0V"
+0["
+0W"
+0X"
+0Y"
+0]"
+0b"
+0^"
+0_"
+0`"
+0d"
+0i"
+0e"
+0f"
+0g"
+0k"
+0p"
+0l"
+0m"
+0n"
+0r"
+0w"
+0s"
+0t"
+0u"
+0y"
+0~"
+0z"
+0{"
+0|"
+0"#
+0'#
+0##
+0$#
+0%#
+0)#
+0.#
+0*#
+0+#
+0,#
+00#
+05#
+01#
+02#
+03#
+07#
+0<#
+08#
+09#
+0:#
+0>#
+0C#
+0?#
+0@#
+0A#
+0E#
+0J#
+0F#
+0G#
+0H#
+0L#
+0Q#
+0M#
+0N#
+0O#
+0S#
+0X#
+0T#
+0U#
+0V#
+0Z#
+0_#
+0[#
+0\#
+0]#
+0a#
+0f#
+0b#
+0c#
+0d#
+0h#
+0m#
+0i#
+0j#
+0k#
+0o#
+0t#
+0p#
+0q#
+0r#
+0v#
+0{#
+0w#
+0x#
+0y#
+0}#
+0$$
+0~#
+0!$
+0"$
+0&$
+0+$
+b0 #
+b0 A
+b0 /$
+0'$
+0($
+0)$
+0P$
+1C$
+0G$
+1*
+0H
+1G
+b0 F
+b10000 J
+b0 I
+05$
+0@$
+0K$
+b0xxxxxxxxxxxxxxxxxx )
+b0xxxxxxxxxxxxxxxxxx A$
+b0xxxxxxxxxxxxxxxxxx N$
+b0 M$
+0+
+0X$
+b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ,
+b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx R$
+b0 Z$
+0-
+14
+1?
+#100000000000000
+04
+0?
+#150000000000000
+14
+1?
+#200000000000000
+04
+0?
+#250000000000000
+14
+1?
+#300000000000000
+04
+0?
+#350000000000000
+14
+1?
+#400000000000000
+04
+0?
+#450000000000000
+14
+1?
+#500000000000000
+04
+0?
+#550000000000000
+14
+1?
+#600000000000000
+04
+0?
+#650000000000000
+14
+1?
+#700000000000000
+04
+0?
+#750000000000000
+14
+1?
+#800000000000000
+04
+0?
+#850000000000000
+14
+1?
+#900000000000000
+04
+0?
+#950000000000000
+14
+1?
+#1000000000000000
+04
+0?
+0<
+0C
+#1050000000000000
+14
+1?
+#1100000000000000
+04
+0?
+#1150000000000000
+1k
+1y
+1""
+1S"
+1Z"
+1}"
+1&#
+14#
+1^#
+1l#
+1s#
+1E
+1:
+b10100000101100001100000011010000 7
+b110100000101100001100000011010000 "
+b110100000101100001100000011010000 @
+1=
+1D
+b100 5
+b1100 [$
+b10100000101100001100000011010000 \$
+14
+1?
+#1200000000000000
+04
+0?
+#1250000000000000
+1F$
+16$
+02
+1>$
+1(
+1%
+1O
+1)"
+1a"
+1;#
+0s#
+0G
+b1111 J
+b1 I
+b1000 5
+b10100001101100011100000111010001 7
+0:
+b10100001101100011100000111010001 "
+b10100001101100011100000111010001 @
+14
+1?
+#1250000000000100
+1E$
+01
+1=$
+b10100000 ?$
+b10100000 .
+b10100000 B$
+1:$
+b11010000010110000 &
+b11010000010110000 -$
+b11010000010110000 7$
+12$
+b1 m
+1l
+b1 {
+1z
+b1 $"
+1#"
+b1 U"
+1T"
+b1 \"
+1["
+b1 !#
+1~"
+b1 (#
+1'#
+b1 6#
+15#
+b1 `#
+1_#
+b1 n#
+1m#
+b1 u#
+1t#
+b110100000101100001100000011010000 #
+b110100000101100001100000011010000 A
+b110100000101100001100000011010000 /$
+#1300000000000000
+04
+0?
+#1350000000000000
+0E$
+0:$
+1.$
+11
+b0 &
+b0 -$
+b0 7$
+1'
+0=$
+02$
+0O
+1V
+0)"
+10"
+0a"
+1h"
+0;#
+1B#
+1z#
+1Q$
+0O$
+b0 ?$
+b0 .
+b0 B$
+1K
+1R
+1Y
+1`
+1g
+0l
+1n
+1u
+0z
+1|
+0#"
+1%"
+1,"
+13"
+1:"
+1A"
+1H"
+1O"
+0T"
+1V"
+0["
+1]"
+1d"
+1k"
+1r"
+1y"
+0~"
+1"#
+0'#
+1)#
+10#
+05#
+17#
+1>#
+1E#
+1L#
+1S#
+1Z#
+0_#
+1a#
+1h#
+0m#
+1o#
+0t#
+b0 #
+b0 A
+b0 /$
+1v#
+1}#
+1&$
+18
+b10100010101100101100001011010010 7
+b1010100010101100101100001011010010 "
+b1010100010101100101100001011010010 @
+b10100000 H$
+b1 M$
+0J$
+1L$
+b110100000xxxxxxxx )
+b110100000xxxxxxxx A$
+b110100000xxxxxxxx N$
+1@$
+b10 I
+b1110 J
+b1 F
+14
+1?
+#1350000000000100
+b10110000 ?$
+b10110000 .
+b10110000 B$
+1:$
+b11010000010110000 &
+b11010000010110000 -$
+b11010000010110000 7$
+12$
+b10 u#
+1t#
+b11 n#
+1m#
+b11 `#
+1_#
+b1 =#
+b11 6#
+15#
+b11 (#
+1'#
+b11 !#
+1~"
+b1 c"
+b11 \"
+1["
+b11 U"
+1T"
+b1 +"
+b11 $"
+1#"
+b11 {
+1z
+b11 m
+1l
+b110100000101100001100000011010000 #
+b110100000101100001100000011010000 A
+b110100000101100001100000011010000 /$
+b1 Q
+#1351000000000000
+1;
+1S$
+#1400000000000000
+04
+0?
+#1450000000000000
+0E$
+0.$
+11
+02$
+0:$
+0'
+0=$
+0K
+1L
+0R
+1S
+0Y
+1Z
+0`
+1a
+0g
+1h
+0l
+0n
+1o
+0u
+1v
+0z
+0|
+1}
+0#"
+0%"
+1&"
+0,"
+1-"
+03"
+14"
+0:"
+1;"
+0A"
+1B"
+0H"
+1I"
+0O"
+1P"
+0T"
+0V"
+1W"
+0["
+0]"
+1^"
+0d"
+1e"
+0k"
+1l"
+0r"
+1s"
+0y"
+1z"
+0~"
+0"#
+1##
+0'#
+0)#
+1*#
+00#
+11#
+05#
+07#
+18#
+0>#
+1?#
+0E#
+1F#
+0L#
+1M#
+0S#
+1T#
+0Z#
+1[#
+0_#
+0a#
+1b#
+0h#
+1i#
+0m#
+0o#
+1p#
+0t#
+b0 #
+b0 A
+b0 /$
+0v#
+1w#
+0}#
+1~#
+0&$
+1'$
+b0 &
+b0 -$
+b0 7$
+b0 ?$
+b0 .
+b0 B$
+1G$
+0E
+0V
+0k
+0y
+0""
+00"
+0S"
+0Z"
+0h"
+0}"
+0&#
+04#
+0B#
+0^#
+0l#
+0z#
+b10 F
+b1101 J
+b11 I
+15$
+0@$
+b10 M$
+1+
+b10110000 I$
+b11010000010110000 )
+b11010000010110000 A$
+b11010000010110000 N$
+0=
+0D
+b0 7
+08
+b0 "
+b0 @
+14
+1?
+#1450000000000100
+b11000000 ?$
+b11000000 .
+b11000000 B$
+b1100000011010000 &
+b1100000011010000 -$
+b1100000011010000 7$
+12$
+b10 Q
+b1 X
+b111 m
+1l
+b111 {
+1z
+b111 $"
+1#"
+b10 +"
+b1 2"
+b111 U"
+1T"
+b111 \"
+1["
+b10 c"
+b1 j"
+b111 !#
+1~"
+b111 (#
+1'#
+b111 6#
+15#
+b10 =#
+b1 D#
+b111 `#
+1_#
+b111 n#
+1m#
+b100 u#
+1t#
+b110100000101100001100000011010000 #
+b110100000101100001100000011010000 A
+b110100000101100001100000011010000 /$
+b1 |#
+#1500000000000000
+04
+0?
+#1550000000000000
+13$
+1B
+1.$
+1$
+1'
+0G$
+0Q$
+b11010000 ?$
+b11010000 .
+b11010000 B$
+b1010000010110000 U$
+b1 Z$
+0W$
+1Y$
+b11010000010110000xxxxxxxxxxxxxxxx ,
+b11010000010110000xxxxxxxxxxxxxxxx R$
+b11000000 H$
+b1 M$
+0+
+0L$
+b1100000010110000 )
+b1100000010110000 A$
+b1100000010110000 N$
+1@$
+14
+1?
+#1600000000000000
+04
+0?
+#1650000000000000
+0E$
+11
+0=$
+03$
+0B
+0.$
+02$
+0:$
+0$
+0'
+1K
+1P
+0L
+1R
+0S
+0W
+1Y
+0Z
+1`
+0a
+1g
+0h
+1n
+0o
+1u
+0v
+1|
+0}
+1%"
+1*"
+0&"
+1,"
+0-"
+01"
+13"
+04"
+1:"
+0;"
+1A"
+0B"
+1H"
+0I"
+1O"
+0P"
+1V"
+0W"
+1]"
+1b"
+0^"
+1d"
+0e"
+0i"
+1k"
+0l"
+1r"
+0s"
+1y"
+0z"
+1"#
+0##
+1)#
+0*#
+10#
+01#
+17#
+1<#
+08#
+1>#
+0?#
+0C#
+1E#
+0F#
+1L#
+0M#
+1S#
+0T#
+1Z#
+0[#
+1a#
+0b#
+1h#
+0i#
+1o#
+0p#
+0t#
+1v#
+0w#
+0{#
+b10100001101100011100000111010001 #
+b10100001101100011100000111010001 A
+b10100001101100011100000111010001 /$
+1}#
+0~#
+1&$
+0'$
+b1010000110110001 &
+b1010000110110001 -$
+b1010000110110001 7$
+b10100001 ?$
+b10100001 .
+b10100001 B$
+1G$
+b1 F
+b1110 J
+b10 I
+05$
+0@$
+b10 M$
+1+
+b11010000 I$
+b1100000011010000 )
+b1100000011010000 A$
+b1100000011010000 N$
+14
+1?
+#1700000000000000
+04
+0?
+#1750000000000000
+1.$
+1'
+1T$
+0G$
+b10110001 ?$
+b10110001 .
+b10110001 B$
+b1100000011010000 V$
+b110100000101100001100000011010000 ,
+b110100000101100001100000011010000 R$
+b10 Z$
+1-
+b10100001 H$
+b1010000111010000 )
+b1010000111010000 A$
+b1010000111010000 N$
+b1 M$
+0+
+1@$
+14
+1?
+#1800000000000000
+04
+0?
+#1850000000000000
+0.$
+0'
+b1100000111010001 &
+b1100000111010001 -$
+b1100000111010001 7$
+b11000001 ?$
+b11000001 .
+b11000001 B$
+1G$
+0T$
+15$
+0@$
+b10 M$
+1+
+b10110001 I$
+b1010000110110001 )
+b1010000110110001 A$
+b1010000110110001 N$
+b0 Z$
+0-
+14
+1?
+#1900000000000000
+04
+0?
+#1950000000000000
+13$
+1B
+1.$
+1$
+1'
+0G$
+b11010001 ?$
+b11010001 .
+b11010001 B$
+b1010000110110001 U$
+b1 Z$
+0Y$
+b10100001101100011100000011010000 ,
+b10100001101100011100000011010000 R$
+b11000001 H$
+b1100000110110001 )
+b1100000110110001 A$
+b1100000110110001 N$
+b1 M$
+0+
+1@$
+14
+1?
+#2000000000000000
+04
+0?
+#2050000000000000
+03$
+0B
+0.$
+10$
+0$
+0'
+0K
+0P
+0R
+1W
+0Y
+0`
+0g
+0n
+0u
+0|
+0%"
+0*"
+0,"
+11"
+03"
+0:"
+0A"
+0H"
+0O"
+0V"
+0]"
+0b"
+0d"
+1i"
+0k"
+0r"
+0y"
+0"#
+0)#
+00#
+07#
+0<#
+0>#
+1C#
+0E#
+0L#
+0S#
+0Z#
+0a#
+0h#
+0o#
+0v#
+1{#
+b1010100010101100101100001011010010 #
+b1010100010101100101100001011010010 A
+b1010100010101100101100001011010010 /$
+0}#
+0&$
+b1010001010110010 &
+b1010001010110010 -$
+b1010001010110010 7$
+b10100010 ?$
+b10100010 .
+b10100010 B$
+1G$
+b0 F
+b1111 J
+b1 I
+05$
+0@$
+b10 M$
+1+
+b11010001 I$
+b1100000111010001 )
+b1100000111010001 A$
+b1100000111010001 N$
+14
+1?
+#2100000000000000
+04
+0?
+#2150000000000000
+1.$
+1'
+1T$
+0G$
+b10110010 ?$
+b10110010 .
+b10110010 B$
+b1100000111010001 V$
+b10100001101100011100000111010001 ,
+b10100001101100011100000111010001 R$
+b10 Z$
+1-
+b10100010 H$
+b1010001011010001 )
+b1010001011010001 A$
+b1010001011010001 N$
+b1 M$
+0+
+1@$
+14
+1?
+#2200000000000000
+04
+0?
+#2250000000000000
+0.$
+18$
+0'
+b101100001011010010 &
+b101100001011010010 -$
+b101100001011010010 7$
+b11000010 ?$
+b11000010 .
+b11000010 B$
+1G$
+0T$
+15$
+0@$
+b10 M$
+1+
+b10110010 I$
+b1010001010110010 )
+b1010001010110010 A$
+b1010001010110010 N$
+b0 Z$
+0-
+14
+1?
+#2300000000000000
+04
+0?
+#2350000000000000
+1D$
+13$
+1B
+00
+1.$
+1$
+1<$
+1'
+0G$
+b11010010 ?$
+b11010010 .
+b11010010 B$
+b1010001010110010 U$
+b10100010101100101100000111010001 ,
+b10100010101100101100000111010001 R$
+b1 Z$
+b11000010 H$
+b1100001010110010 )
+b1100001010110010 A$
+b1100001010110010 N$
+b1 M$
+0+
+1@$
+14
+1?
+#2400000000000000
+04
+0?
+#2450000000000000
+0D$
+0'
+0F$
+10
+0.$
+06$
+12
+03$
+0B
+08$
+0$
+0<$
+0>$
+0(
+0%
+b1010001010110010 &
+b1010001010110010 -$
+b1010001010110010 7$
+b10100010 ?$
+b10100010 .
+b10100010 B$
+1G$
+1O$
+1G
+b10000 J
+b0 I
+05$
+0@$
+1J$
+b10 M$
+1+
+b11010010 I$
+b101100001011010010 )
+b101100001011010010 A$
+b101100001011010010 N$
+14
+1?
+#2500000000000000
+04
+0?
+#2550000000000000
+1T$
+0G$
+b1100001011010010 V$
+b10 Z$
+1-
+1W$
+b1010100010101100101100001011010010 ,
+b1010100010101100101100001011010010 R$
+b0 M$
+0+
+14
+1?
+#2600000000000000
+04
+0?
+#2650000000000000
+0T$
+b0 Z$
+0-
+14
+1?
+#2700000000000000
+04
+0?
+#2750000000000000
+14
+1?
+#2800000000000000
+04
+0?
+#2850000000000000
+14
+1?
+#2900000000000000
+04
+0?
+#2950000000000000
+14
+1?
+#3000000000000000
+04
+0?
+#3050000000000000
+14
+1?
+#3100000000000000
+04
+0?
+#3150000000000000
+14
+1?
+#3200000000000000
+04
+0?
+#3250000000000000
+14
+1?
+#3300000000000000
+04
+0?
+#3350000000000000
+14
+1?
+#3400000000000000
+04
+0?
+#3450000000000000
+14
+1?
+#3500000000000000
+04
+0?
+#3550000000000000
+14
+1?
+#3600000000000000
+04
+0?
+#3650000000000000
+14
+1?
+#3700000000000000
+04
+0?
+#3750000000000000
+14
+1?
+#3800000000000000
+04
+0?
+#3850000000000000
+14
+1?
+#3900000000000000
+04
+0?
+#3950000000000000
+14
+1?
+#4000000000000000
+04
+0?
+#4050000000000000
+14
+1?
+#4100000000000000
+04
+0?
+#4150000000000000
+14
+1?
+#4200000000000000
+04
+0?
+#4250000000000000
+14
+1?
+#4300000000000000
+04
+0?
+#4350000000000000
+14
+1?
+#4400000000000000
+04
+0?
+#4450000000000000
+14
+1?
+#4500000000000000
+04
+0?
+#4550000000000000
+14
+1?
+#4600000000000000
+04
+0?
+#4650000000000000
+14
+1?
+#4700000000000000
+04
+0?
+#4750000000000000
+14
+1?
+#4800000000000000
+04
+0?
+#4850000000000000
+14
+1?
+#4900000000000000
+04
+0?
+#4950000000000000
+14
+1?
+#5000000000000000
+04
+0?
+#5050000000000000
+14
+1?
+#5100000000000000
+04
+0?
+#5150000000000000
+14
+1?
+#5200000000000000
+04
+0?
+#5250000000000000
+14
+1?
+#5300000000000000
+04
+0?
+#5350000000000000
+14
+1?
+#5400000000000000
+04
+0?
+#5450000000000000
+14
+1?
+#5500000000000000
+04
+0?
+#5550000000000000
+14
+1?
+#5600000000000000
+04
+0?
+#5650000000000000
+14
+1?
+#5700000000000000
+04
+0?
+#5750000000000000
+14
+1?
+#5800000000000000
+04
+0?
+#5850000000000000
+14
+1?
+#5900000000000000
+04
+0?
+#5950000000000000
+14
+1?
+#6000000000000000
+04
+0?
+#6050000000000000
+14
+1?
+#6100000000000000
+04
+0?
+#6150000000000000
+14
+1?
+#6200000000000000
+04
+0?
+#6250000000000000
+14
+1?
+#6300000000000000
+04
+0?
+#6350000000000000
+14
+1?
+#6400000000000000
+04
+0?
+#6450000000000000
+14
+1?
+#6500000000000000
+04
+0?
+#6550000000000000
+14
+1?
+#6600000000000000
+04
+0?
+#6650000000000000
+14
+1?
+#6700000000000000
+04
+0?
+#6750000000000000
+14
+1?
+#6800000000000000
+04
+0?
+#6850000000000000
+14
+1?
+#6900000000000000
+04
+0?
+#6950000000000000
+14
+1?
+#7000000000000000
+04
+0?
+#7050000000000000
+14
+1?
+#7100000000000000
+04
+0?
+#7150000000000000
+14
+1?
+#7200000000000000
+04
+0?
+#7250000000000000
+14
+1?
+#7300000000000000
+04
+0?
+#7350000000000000
+14
+1?
+#7400000000000000
+04
+0?
+#7450000000000000
+14
+1?
+#7500000000000000
+04
+0?
+#7550000000000000
+14
+1?
+#7600000000000000
+04
+0?
+#7650000000000000
+14
+1?
+#7700000000000000
+04
+0?
+#7750000000000000
+14
+1?
+#7800000000000000
+04
+0?
+#7850000000000000
+14
+1?
+#7900000000000000
+04
+0?
+#7950000000000000
+14
+1?
+#8000000000000000
+04
+0?
+#8050000000000000
+14
+1?
+#8100000000000000
+04
+0?
+#8150000000000000
+14
+1?
+#8200000000000000
+04
+0?
+#8250000000000000
+14
+1?
+#8300000000000000
+04
+0?
+#8350000000000000
+14
+1?
+#8400000000000000
+04
+0?
+#8450000000000000
+14
+1?
+#8500000000000000
+04
+0?
+#8550000000000000
+14
+1?
+#8600000000000000
+04
+0?
+#8650000000000000
+14
+1?
+#8700000000000000
+04
+0?
+#8750000000000000
+14
+1?
+#8800000000000000
+04
+0?
+#8850000000000000
+14
+1?
+#8900000000000000
+04
+0?
+#8950000000000000
+14
+1?
+#9000000000000000
+04
+0?
+#9050000000000000
+14
+1?
+#9100000000000000
+04
+0?
+#9150000000000000
+14
+1?
+#9200000000000000
+04
+0?
+#9250000000000000
+14
+1?
+#9300000000000000
+04
+0?
+#9350000000000000
+14
+1?
+#9400000000000000
+04
+0?
+#9450000000000000
+14
+1?
+#9500000000000000
+04
+0?
+#9550000000000000
+14
+1?
+#9600000000000000
+04
+0?
+#9650000000000000
+14
+1?
+#9700000000000000
+04
+0?
+#9750000000000000
+14
+1?
+#9800000000000000
+04
+0?
+#9850000000000000
+14
+1?
+#9900000000000000
+04
+0?
+#9950000000000000
+14
+1?
+#10000000000000000
+04
+0?
+#10050000000000000
+14
+1?
+#10100000000000000
+04
+0?
+#10150000000000000
+14
+1?
+#10200000000000000
+04
+0?
+#10250000000000000
+14
+1?
+#10300000000000000
+04
+0?
+#10350000000000000
+14
+1?
+#10400000000000000
+04
+0?
+#10450000000000000
+14
+1?
+#10500000000000000
+04
+0?
+#10550000000000000
+14
+1?
+#10600000000000000
+04
+0?
+#10650000000000000
+14
+1?
+#10700000000000000
+04
+0?
+#10750000000000000
+14
+1?
+#10800000000000000
+04
+0?
+#10850000000000000
+14
+1?
+#10900000000000000
+04
+0?
+#10950000000000000
+14
+1?
+#11000000000000000
+04
+0?
+#11050000000000000
+14
+1?
+#11100000000000000
+04
+0?
+#11150000000000000
+14
+1?
+#11200000000000000
+04
+0?
+#11250000000000000
+14
+1?
+#11300000000000000
+04
+0?
+#11350000000000000
+14
+1?
+#11400000000000000
+04
+0?
+#11450000000000000
+14
+1?
+#11500000000000000
+04
+0?
+#11550000000000000
+14
+1?
+#11600000000000000
+04
+0?
+#11650000000000000
+1k
+1r
+1""
+1L"
+1Z"
+1}"
+1&#
+1-#
+14#
+1^#
+1e#
+1l#
+1s#
+1E
+1:
+b11100000111100001010000010110000 7
+b111100000111100001010000010110000 "
+b111100000111100001010000010110000 @
+1=
+1D
+b100 5
+b100100 [$
+b11100000111100001010000010110000 \$
+14
+1?
+#11700000000000000
+04
+0?
+#11750000000000000
+1F$
+16$
+02
+1>$
+1(
+1%
+1O
+1)"
+1a"
+1;#
+0s#
+b1 I
+b1111 J
+0G
+b1000 5
+b11100001111100011010000110110001 7
+0:
+b11100001111100011010000110110001 "
+b11100001111100011010000110110001 @
+14
+1?
+#11750000000000100
+1E$
+01
+1=$
+b11100000 ?$
+b11100000 .
+b11100000 B$
+1:$
+b11110000011110000 &
+b11110000011110000 -$
+b11110000011110000 7$
+12$
+00$
+b10 |#
+0{#
+b1001 u#
+1t#
+b1111 n#
+b1 g#
+1f#
+b1111 `#
+b10 D#
+0C#
+b100 =#
+b1111 6#
+b1 /#
+1.#
+b1111 (#
+b1111 !#
+b10 j"
+0i"
+b100 c"
+b1111 \"
+b1110 U"
+0T"
+b1 N"
+1M"
+b10 2"
+01"
+b100 +"
+b1111 $"
+b1110 {
+0z
+b1 t
+1s
+b1111 m
+b10 X
+0W
+b111100000111100001010000010110000 #
+b111100000111100001010000010110000 A
+b111100000111100001010000010110000 /$
+b100 Q
+#11800000000000000
+04
+0?
+#11850000000000000
+0:$
+0E$
+b1010001010110010 &
+b1010001010110010 -$
+b1010001010110010 7$
+1.$
+11
+02$
+10$
+1'
+0=$
+0O
+1V
+0)"
+10"
+0a"
+1h"
+0;#
+1B#
+1K
+1R
+1W
+1Y
+1`
+1g
+1n
+0s
+1u
+1z
+1|
+1%"
+1,"
+11"
+13"
+1:"
+1A"
+1H"
+0M"
+1O"
+1T"
+1V"
+1]"
+1d"
+1i"
+1k"
+1r"
+1y"
+1"#
+1)#
+0.#
+10#
+17#
+1>#
+1C#
+1E#
+1L#
+1S#
+1Z#
+1a#
+0f#
+1h#
+1o#
+0t#
+1v#
+1{#
+b1010100010101100101100001011010010 #
+b1010100010101100101100001011010010 A
+b1010100010101100101100001011010010 /$
+1}#
+1&$
+b10110010 ?$
+b10110010 .
+b10110010 B$
+1Q$
+0O$
+b1100 5
+b11100010111100101010001010110010 7
+b11100010111100101010001010110010 "
+b11100010111100101010001010110010 @
+b1 F
+b1110 J
+b10 I
+1@$
+1L$
+0J$
+b1 M$
+b11100000 H$
+b11110000011010010 )
+b11110000011010010 A$
+b11110000011010010 N$
+14
+1?
+#11850000000000100
+b11110000 ?$
+b11110000 .
+b11110000 B$
+1:$
+b11110000011110000 &
+b11110000011110000 -$
+b11110000011110000 7$
+12$
+00$
+b1001 Q
+b100 X
+0W
+b11111 m
+b11 t
+1s
+b11100 {
+0z
+b11111 $"
+b1001 +"
+b100 2"
+01"
+b11 N"
+1M"
+b11100 U"
+0T"
+b11111 \"
+b1001 c"
+b100 j"
+0i"
+b11111 !#
+b11111 (#
+b11 /#
+1.#
+b11111 6#
+b1001 =#
+b100 D#
+0C#
+b11111 `#
+b11 g#
+1f#
+b11111 n#
+b10010 u#
+1t#
+b100 |#
+0{#
+b111100000111100001010000010110000 #
+b111100000111100001010000010110000 A
+b111100000111100001010000010110000 /$
+#11900000000000000
+04
+0?
+#11950000000000000
+18$
+0.$
+03$
+0B
+0'
+0:$
+0$
+02$
+10$
+1G$
+b11000010 ?$
+b11000010 .
+b11000010 B$
+b101100001011010010 &
+b101100001011010010 -$
+b101100001011010010 7$
+0K
+1L
+0P
+0R
+1W
+1S
+0Y
+1Z
+0`
+1a
+0g
+1h
+0n
+1o
+0s
+0u
+1v
+1z
+0|
+1}
+0%"
+1&"
+0*"
+0,"
+11"
+1-"
+03"
+14"
+0:"
+1;"
+0A"
+1B"
+0H"
+1I"
+0M"
+0O"
+1P"
+1T"
+0V"
+1W"
+0]"
+1^"
+0b"
+0d"
+1i"
+1e"
+0k"
+1l"
+0r"
+1s"
+0y"
+1z"
+0"#
+1##
+0)#
+1*#
+0.#
+00#
+11#
+07#
+18#
+0<#
+0>#
+1C#
+1?#
+0E#
+1F#
+0L#
+1M#
+0S#
+1T#
+0Z#
+1[#
+0a#
+1b#
+0f#
+0h#
+1i#
+0o#
+1p#
+0t#
+0v#
+1{#
+b1010100010101100101100001011010010 #
+b1010100010101100101100001011010010 A
+b1010100010101100101100001011010010 /$
+1w#
+0}#
+1~#
+0&$
+1'$
+1O
+1)"
+1a"
+1;#
+b11110000 I$
+b11110000011110000 )
+b11110000011110000 A$
+b11110000011110000 N$
+b10 M$
+1+
+0@$
+15$
+b11 I
+b1101 J
+b10 F
+b10000 5
+b11100011111100111010001110110011 7
+b11100011111100111010001110110011 "
+b11100011111100111010001110110011 @
+14
+1?
+#11950000000000100
+b10100000 ?$
+b10100000 .
+b10100000 B$
+08$
+b1010000010110000 &
+b1010000010110000 -$
+b1010000010110000 7$
+12$
+00$
+b1000 |#
+0{#
+b100100 u#
+1t#
+b111111 n#
+b111 g#
+1f#
+b111111 `#
+b1001 D#
+0C#
+b10010 =#
+b111111 6#
+b111 /#
+1.#
+b111111 (#
+b111111 !#
+b1001 j"
+0i"
+b10010 c"
+b111111 \"
+b111000 U"
+0T"
+b111 N"
+1M"
+b1001 2"
+01"
+b10010 +"
+b111111 $"
+b111000 {
+0z
+b111 t
+1s
+b111111 m
+b1001 X
+0W
+b111100000111100001010000010110000 #
+b111100000111100001010000010110000 A
+b111100000111100001010000010110000 /$
+b10010 Q
+#12000000000000000
+04
+0?
+#12050000000000000
+1D$
+00
+1<$
+18$
+13$
+1B
+b101100001011010010 &
+b101100001011010010 -$
+b101100001011010010 7$
+1.$
+1$
+02$
+10$
+1'
+0O
+0V
+1]
+0)"
+00"
+17"
+0a"
+0h"
+1o"
+0;#
+0B#
+1I#
+1K
+1R
+1W
+1Y
+1`
+1g
+1n
+0s
+1u
+1z
+1|
+1%"
+1,"
+11"
+13"
+1:"
+1A"
+1H"
+0M"
+1O"
+1T"
+1V"
+1]"
+1d"
+1i"
+1k"
+1r"
+1y"
+1"#
+1)#
+0.#
+10#
+17#
+1>#
+1C#
+1E#
+1L#
+1S#
+1Z#
+1a#
+0f#
+1h#
+1o#
+0t#
+1v#
+1{#
+b1010100010101100101100001011010010 #
+b1010100010101100101100001011010010 A
+b1010100010101100101100001011010010 /$
+1}#
+1&$
+b11010010 ?$
+b11010010 .
+b11010010 B$
+0G$
+0Q$
+b10100 5
+b11100100111101001010010010110100 7
+b11100100111101001010010010110100 "
+b11100100111101001010010010110100 @
+b11 F
+b1100 J
+b100 I
+1@$
+0L$
+b1 M$
+0+
+b10100000 H$
+b1010000011110000 )
+b1010000011110000 A$
+b1010000011110000 N$
+1Y$
+0W$
+b1 Z$
+b1110000011110000 U$
+b111100000111100001100001011010010 ,
+b111100000111100001100001011010010 R$
+14
+1?
+#12050000000000100
+0D$
+10
+0<$
+b10110000 ?$
+b10110000 .
+b10110000 B$
+08$
+b1010000010110000 &
+b1010000010110000 -$
+b1010000010110000 7$
+12$
+00$
+b100101 Q
+b10011 X
+0W
+b1111111 m
+b1111 t
+1s
+b1110000 {
+0z
+b1111111 $"
+b100101 +"
+b10011 2"
+01"
+b1111 N"
+1M"
+b1110000 U"
+0T"
+b1111111 \"
+b100101 c"
+b10011 j"
+0i"
+b1111111 !#
+b1111111 (#
+b1111 /#
+1.#
+b1111111 6#
+b100101 =#
+b10011 D#
+0C#
+b1111111 `#
+b1111 g#
+1f#
+b1111111 n#
+b1001000 u#
+1t#
+b10000 |#
+0{#
+b111100000111100001010000010110000 #
+b111100000111100001010000010110000 A
+b111100000111100001010000010110000 /$
+#12100000000000000
+04
+0?
+#12150000000000000
+1E$
+0.$
+01
+03$
+0B
+0'
+1=$
+1:$
+0$
+1G$
+b11100000 ?$
+b11100000 .
+b11100000 B$
+b11110000011110000 &
+b11110000011110000 -$
+b11110000011110000 7$
+1O
+1)"
+1a"
+1;#
+b10110000 I$
+b1010000010110000 )
+b1010000010110000 A$
+b1010000010110000 N$
+b10 M$
+1+
+0@$
+05$
+b11000 5
+b11100101111101011010010110110101 7
+b11100101111101011010010110110101 "
+b11100101111101011010010110110101 @
+14
+1?
+#12150000000000100
+0E$
+11
+0=$
+b11100001 ?$
+b11100001 .
+b11100001 B$
+0:$
+b1110000111110001 &
+b1110000111110001 -$
+b1110000111110001 7$
+02$
+b100000 |#
+b10010000 u#
+0t#
+b11111111 n#
+b11111 g#
+b11111111 `#
+b1 K#
+b100110 D#
+b1001010 =#
+1<#
+b11111111 6#
+b11111 /#
+b11111111 (#
+b11111111 !#
+b1 q"
+b100110 j"
+b1001010 c"
+1b"
+b11111111 \"
+b11100000 U"
+b11111 N"
+b1 9"
+b100110 2"
+b1001010 +"
+1*"
+b11111111 $"
+b11100000 {
+b11111 t
+b11111111 m
+b1 _
+b100110 X
+b1001010 Q
+1P
+b11100001111100011010000110110001 #
+b11100001111100011010000110110001 A
+b11100001111100011010000110110001 /$
+#12200000000000000
+04
+0?
+#12250000000000000
+1:$
+b11110000011110000 &
+b11110000011110000 -$
+b11110000011110000 7$
+1.$
+12$
+1'
+0O
+1V
+0)"
+10"
+0a"
+1h"
+0;#
+1B#
+0K
+0L
+1M
+0P
+0R
+0S
+0W
+1T
+0Y
+0Z
+1[
+0`
+0a
+1b
+0g
+0h
+1i
+0n
+0o
+1p
+1s
+0u
+0v
+1w
+0z
+0|
+0}
+1~
+0%"
+0&"
+1'"
+0*"
+0,"
+0-"
+01"
+1."
+03"
+04"
+15"
+0:"
+0;"
+1<"
+0A"
+0B"
+1C"
+0H"
+0I"
+1J"
+1M"
+0O"
+0P"
+1Q"
+0T"
+0V"
+0W"
+1X"
+0]"
+0^"
+1_"
+0b"
+0d"
+0e"
+0i"
+1f"
+0k"
+0l"
+1m"
+0r"
+0s"
+1t"
+0y"
+0z"
+1{"
+0"#
+0##
+1$#
+0)#
+0*#
+1+#
+1.#
+00#
+01#
+12#
+07#
+08#
+19#
+0<#
+0>#
+0?#
+0C#
+1@#
+0E#
+0F#
+1G#
+0L#
+0M#
+1N#
+0S#
+0T#
+1U#
+0Z#
+0[#
+1\#
+0a#
+0b#
+1c#
+1f#
+0h#
+0i#
+1j#
+0o#
+0p#
+1q#
+1t#
+0v#
+0w#
+0{#
+b111100000111100001010000010110000 #
+b111100000111100001010000010110000 A
+b111100000111100001010000010110000 /$
+1x#
+0}#
+0~#
+1!$
+0&$
+0'$
+1($
+b11110000 ?$
+b11110000 .
+b11110000 B$
+0G$
+1T$
+b11100 5
+b11100110111101101010011010110110 7
+b11100110111101101010011010110110 "
+b11100110111101101010011010110110 @
+b100 F
+b1011 J
+b101 I
+1@$
+b1 M$
+0+
+b11100001 H$
+b1110000110110000 )
+b1110000110110000 A$
+b1110000110110000 N$
+b10 Z$
+1-
+b1010000010110000 V$
+b111100000111100001010000010110000 ,
+b111100000111100001010000010110000 R$
+14
+1?
+#12250000000000100
+b11110001 ?$
+b11110001 .
+b11110001 B$
+0:$
+b1110000111110001 &
+b1110000111110001 -$
+b1110000111110001 7$
+02$
+b10010101 Q
+1P
+b1001100 X
+b11 _
+b111111111 m
+b111111 t
+b111000000 {
+b111111111 $"
+b10010101 +"
+1*"
+b1001100 2"
+b11 9"
+b111111 N"
+b111000000 U"
+b111111111 \"
+b10010101 c"
+1b"
+b1001100 j"
+b11 q"
+b111111111 !#
+b111111111 (#
+b111111 /#
+b111111111 6#
+b10010101 =#
+1<#
+b1001100 D#
+b11 K#
+b111111111 `#
+b111111 g#
+b111111111 n#
+b100100000 u#
+0t#
+b11100001111100011010000110110001 #
+b11100001111100011010000110110001 A
+b11100001111100011010000110110001 /$
+b1000000 |#
+#12300000000000000
+04
+0?
+#12350000000000000
+0.$
+03$
+0B
+0'
+0$
+12$
+0T$
+1G$
+b10100000 ?$
+b10100000 .
+b10100000 B$
+b1010000010110000 &
+b1010000010110000 -$
+b1010000010110000 7$
+1K
+0P
+1R
+1Y
+1`
+1g
+1n
+1u
+1|
+1%"
+0*"
+1,"
+13"
+1:"
+1A"
+1H"
+1O"
+1V"
+1]"
+0b"
+1d"
+1k"
+1r"
+1y"
+1"#
+1)#
+10#
+17#
+0<#
+1>#
+1E#
+1L#
+1S#
+1Z#
+1a#
+1h#
+1o#
+1t#
+b111100000111100001010000010110000 #
+b111100000111100001010000010110000 A
+b111100000111100001010000010110000 /$
+1v#
+1}#
+1&$
+1O
+1)"
+1a"
+1;#
+b0 Z$
+0-
+b11110001 I$
+b1110000111110001 )
+b1110000111110001 A$
+b1110000111110001 N$
+b10 M$
+1+
+0@$
+15$
+b110 I
+b1010 J
+b101 F
+b100000 5
+b11100111111101111010011110110111 7
+b11100111111101111010011110110111 "
+b11100111111101111010011110110111 @
+14
+1?
+#12350000000000100
+b10100001 ?$
+b10100001 .
+b10100001 B$
+b1010000110110001 &
+b1010000110110001 -$
+b1010000110110001 7$
+02$
+b10000000 |#
+b1001000000 u#
+0t#
+b1111111111 n#
+b1111111 g#
+b1111111111 `#
+b111 K#
+b10011001 D#
+b100101010 =#
+1<#
+b1111111111 6#
+b1111111 /#
+b1111111111 (#
+b1111111111 !#
+b111 q"
+b10011001 j"
+b100101010 c"
+1b"
+b1111111111 \"
+b1110000000 U"
+b1111111 N"
+b111 9"
+b10011001 2"
+b100101010 +"
+1*"
+b1111111111 $"
+b1110000000 {
+b1111111 t
+b1111111111 m
+b111 _
+b10011001 X
+b100101010 Q
+1P
+b11100001111100011010000110110001 #
+b11100001111100011010000110110001 A
+b11100001111100011010000110110001 /$
+#12400000000000000
+04
+0?
+#12450000000000000
+13$
+1B
+b1010000010110000 &
+b1010000010110000 -$
+b1010000010110000 7$
+1.$
+1$
+12$
+1'
+0O
+0V
+0]
+1d
+0)"
+00"
+07"
+1>"
+0a"
+0h"
+0o"
+1v"
+0;#
+0B#
+0I#
+1P#
+1z#
+0K
+1L
+0P
+0R
+1S
+0W
+0Y
+1Z
+0`
+1a
+0g
+1h
+0n
+1o
+1s
+0u
+1v
+0z
+0|
+1}
+0%"
+1&"
+0*"
+0,"
+1-"
+01"
+03"
+14"
+0:"
+1;"
+0A"
+1B"
+0H"
+1I"
+1M"
+0O"
+1P"
+0T"
+0V"
+1W"
+0]"
+1^"
+0b"
+0d"
+1e"
+0i"
+0k"
+1l"
+0r"
+1s"
+0y"
+1z"
+0"#
+1##
+0)#
+1*#
+1.#
+00#
+11#
+07#
+18#
+0<#
+0>#
+1?#
+0C#
+0E#
+1F#
+0L#
+1M#
+0S#
+1T#
+0Z#
+1[#
+0a#
+1b#
+1f#
+0h#
+1i#
+0o#
+1t#
+1p#
+0v#
+1w#
+0{#
+b111100000111100001010000010110000 #
+b111100000111100001010000010110000 A
+b111100000111100001010000010110000 /$
+0}#
+1~#
+0&$
+1'$
+b10110000 ?$
+b10110000 .
+b10110000 B$
+0G$
+18
+b11101000111110001010100010111000 7
+b1011101000111110001010100010111000 "
+b1011101000111110001010100010111000 @
+b110 F
+b1001 J
+b111 I
+1@$
+b1 M$
+0+
+b10100001 H$
+b1010000111110001 )
+b1010000111110001 A$
+b1010000111110001 N$
+0Y$
+b1 Z$
+b1110000111110001 U$
+b11100001111100011010000010110000 ,
+b11100001111100011010000010110000 R$
+14
+1?
+#12450000000000100
+b10110001 ?$
+b10110001 .
+b10110001 B$
+b1010000110110001 &
+b1010000110110001 -$
+b1010000110110001 7$
+02$
+b1001010101 Q
+1P
+b100110011 X
+b1111 _
+b11111111111 m
+b11111111 t
+b11100000000 {
+b11111111111 $"
+b1001010101 +"
+1*"
+b100110011 2"
+b1111 9"
+b11111111 N"
+b11100000000 U"
+b11111111111 \"
+b1001010101 c"
+1b"
+b100110011 j"
+b1111 q"
+b11111111111 !#
+b11111111111 (#
+b11111111 /#
+b11111111111 6#
+b1001010101 =#
+1<#
+b100110011 D#
+b1111 K#
+b11111111111 `#
+b11111111 g#
+b11111111111 n#
+b10010000000 u#
+0t#
+b11100001111100011010000110110001 #
+b11100001111100011010000110110001 A
+b11100001111100011010000110110001 /$
+b100000000 |#
+#12500000000000000
+04
+0?
+#12550000000000000
+0.$
+03$
+0B
+0'
+0$
+1G$
+b11100001 ?$
+b11100001 .
+b11100001 B$
+b1110000111110001 &
+b1110000111110001 -$
+b1110000111110001 7$
+0E
+0d
+0k
+0r
+0""
+0>"
+0L"
+0Z"
+0v"
+0}"
+0&#
+0-#
+04#
+0P#
+0^#
+0e#
+0l#
+0z#
+b10110001 I$
+b1010000110110001 )
+b1010000110110001 A$
+b1010000110110001 N$
+b10 M$
+1+
+0@$
+05$
+0=
+0D
+b0 7
+08
+b0 "
+b0 @
+14
+1?
+#12550000000000100
+b11100010 ?$
+b11100010 .
+b11100010 B$
+b1110001011110010 &
+b1110001011110010 -$
+b1110001011110010 7$
+b1000000001 |#
+b100100000000 u#
+b111111111111 n#
+b111111111 g#
+b111111111111 `#
+b1 R#
+b11110 K#
+b1001100110 D#
+1C#
+b10010101010 =#
+0<#
+b111111111111 6#
+b111111111 /#
+b111111111111 (#
+b111111111111 !#
+b1 x"
+b11110 q"
+b1001100110 j"
+1i"
+b10010101010 c"
+0b"
+b111111111111 \"
+b111000000000 U"
+b111111111 N"
+b1 @"
+b11110 9"
+b1001100110 2"
+11"
+b10010101010 +"
+0*"
+b111111111111 $"
+b111000000000 {
+b111111111 t
+b111111111111 m
+b1 f
+b11110 _
+b1001100110 X
+1W
+b10010101010 Q
+0P
+b11100010111100101010001010110010 #
+b11100010111100101010001010110010 A
+b11100010111100101010001010110010 /$
+#12600000000000000
+04
+0?
+#12650000000000000
+1.$
+1'
+b11110010 ?$
+b11110010 .
+b11110010 B$
+0G$
+1T$
+1@$
+b1 M$
+0+
+b11100010 H$
+b1110001010110001 )
+b1110001010110001 A$
+b1110001010110001 N$
+b10 Z$
+1-
+b1010000110110001 V$
+b11100001111100011010000110110001 ,
+b11100001111100011010000110110001 R$
+14
+1?
+#12700000000000000
+04
+0?
+#12750000000000000
+0.$
+03$
+0B
+0'
+0$
+0T$
+1G$
+b10100010 ?$
+b10100010 .
+b10100010 B$
+b1010001010110010 &
+b1010001010110010 -$
+b1010001010110010 7$
+b0 Z$
+0-
+b11110010 I$
+b1110001011110010 )
+b1110001011110010 A$
+b1110001011110010 N$
+b10 M$
+1+
+0@$
+15$
+14
+1?
+#12800000000000000
+04
+0?
+#12850000000000000
+13$
+1B
+1.$
+1$
+1'
+b10110010 ?$
+b10110010 .
+b10110010 B$
+0G$
+1@$
+b1 M$
+0+
+b10100010 H$
+b1010001011110010 )
+b1010001011110010 A$
+b1010001011110010 N$
+b1 Z$
+b1110001011110010 U$
+b11100010111100101010000110110001 ,
+b11100010111100101010000110110001 R$
+14
+1?
+#12900000000000000
+04
+0?
+#12950000000000000
+0.$
+03$
+0B
+0'
+0$
+1G$
+b11100011 ?$
+b11100011 .
+b11100011 B$
+b1110001111110011 &
+b1110001111110011 -$
+b1110001111110011 7$
+1K
+1P
+0L
+1R
+0S
+1W
+1Y
+0Z
+0^
+1`
+0a
+1g
+0h
+1n
+0o
+1u
+0v
+1|
+0}
+1%"
+1*"
+0&"
+1,"
+0-"
+11"
+13"
+04"
+08"
+1:"
+0;"
+1A"
+0B"
+1H"
+0I"
+1O"
+0P"
+1V"
+0W"
+1]"
+1b"
+0^"
+1d"
+0e"
+1i"
+1k"
+0l"
+0p"
+1r"
+0s"
+1y"
+0z"
+1"#
+0##
+1)#
+0*#
+10#
+01#
+17#
+1<#
+08#
+1>#
+0?#
+1C#
+1E#
+0F#
+0J#
+b11100011111100111010001110110011 #
+b11100011111100111010001110110011 A
+b11100011111100111010001110110011 /$
+1L#
+0M#
+1S#
+0T#
+1Z#
+0[#
+1a#
+0b#
+1h#
+0i#
+1o#
+0p#
+1v#
+0w#
+1}#
+0~#
+1&$
+0'$
+b10110010 I$
+b1010001010110010 )
+b1010001010110010 A$
+b1010001010110010 N$
+b10 M$
+1+
+0@$
+05$
+b110 I
+b1010 J
+b101 F
+14
+1?
+#13000000000000000
+04
+0?
+#13050000000000000
+1.$
+1'
+b11110011 ?$
+b11110011 .
+b11110011 B$
+0G$
+1T$
+1@$
+b1 M$
+0+
+b11100011 H$
+b1110001110110010 )
+b1110001110110010 A$
+b1110001110110010 N$
+b10 Z$
+1-
+b1010001010110010 V$
+b11100010111100101010001010110010 ,
+b11100010111100101010001010110010 R$
+14
+1?
+#13100000000000000
+04
+0?
+#13150000000000000
+0.$
+03$
+0B
+0'
+0$
+0T$
+1G$
+b10100011 ?$
+b10100011 .
+b10100011 B$
+b1010001110110011 &
+b1010001110110011 -$
+b1010001110110011 7$
+b0 Z$
+0-
+b11110011 I$
+b1110001111110011 )
+b1110001111110011 A$
+b1110001111110011 N$
+b10 M$
+1+
+0@$
+15$
+14
+1?
+#13200000000000000
+04
+0?
+#13250000000000000
+13$
+1B
+1.$
+1$
+1'
+b10110011 ?$
+b10110011 .
+b10110011 B$
+0G$
+1@$
+b1 M$
+0+
+b10100011 H$
+b1010001111110011 )
+b1010001111110011 A$
+b1010001111110011 N$
+b1 Z$
+b1110001111110011 U$
+b11100011111100111010001010110010 ,
+b11100011111100111010001010110010 R$
+14
+1?
+#13300000000000000
+04
+0?
+#13350000000000000
+0.$
+03$
+0B
+0'
+0$
+1G$
+b11100100 ?$
+b11100100 .
+b11100100 B$
+b1110010011110100 &
+b1110010011110100 -$
+b1110010011110100 7$
+0K
+0P
+0R
+0W
+0Y
+1^
+0`
+0g
+0n
+0u
+0|
+0%"
+0*"
+0,"
+01"
+03"
+18"
+0:"
+0A"
+0H"
+0O"
+0V"
+0]"
+0b"
+0d"
+0i"
+0k"
+1p"
+0r"
+0y"
+0"#
+0)#
+00#
+07#
+0<#
+0>#
+0C#
+0E#
+1J#
+b11100100111101001010010010110100 #
+b11100100111101001010010010110100 A
+b11100100111101001010010010110100 /$
+0L#
+0S#
+0Z#
+0a#
+0h#
+0o#
+0v#
+0}#
+0&$
+b10110011 I$
+b1010001110110011 )
+b1010001110110011 A$
+b1010001110110011 N$
+b10 M$
+1+
+0@$
+05$
+b101 I
+b1011 J
+b100 F
+14
+1?
+#13400000000000000
+04
+0?
+#13450000000000000
+1.$
+1'
+b11110100 ?$
+b11110100 .
+b11110100 B$
+0G$
+1T$
+1@$
+b1 M$
+0+
+b11100100 H$
+b1110010010110011 )
+b1110010010110011 A$
+b1110010010110011 N$
+b10 Z$
+1-
+b1010001110110011 V$
+b11100011111100111010001110110011 ,
+b11100011111100111010001110110011 R$
+14
+1?
+#13500000000000000
+04
+0?
+#13550000000000000
+0.$
+03$
+0B
+0'
+0$
+0T$
+1G$
+b10100100 ?$
+b10100100 .
+b10100100 B$
+b1010010010110100 &
+b1010010010110100 -$
+b1010010010110100 7$
+b0 Z$
+0-
+b11110100 I$
+b1110010011110100 )
+b1110010011110100 A$
+b1110010011110100 N$
+b10 M$
+1+
+0@$
+15$
+14
+1?
+#13600000000000000
+04
+0?
+#13650000000000000
+13$
+1B
+1.$
+1$
+1'
+b10110100 ?$
+b10110100 .
+b10110100 B$
+0G$
+1@$
+b1 M$
+0+
+b10100100 H$
+b1010010011110100 )
+b1010010011110100 A$
+b1010010011110100 N$
+b1 Z$
+b1110010011110100 U$
+b11100100111101001010001110110011 ,
+b11100100111101001010001110110011 R$
+14
+1?
+#13700000000000000
+04
+0?
+#13750000000000000
+0.$
+03$
+0B
+0'
+0$
+1G$
+b11100101 ?$
+b11100101 .
+b11100101 B$
+b1110010111110101 &
+b1110010111110101 -$
+b1110010111110101 7$
+1K
+1P
+1L
+0M
+1R
+1S
+0W
+0T
+1Y
+1Z
+0[
+1^
+1`
+1a
+0b
+0e
+1g
+1h
+0i
+1n
+1o
+0p
+1u
+1v
+0w
+1|
+1}
+0~
+1%"
+1*"
+1&"
+0'"
+1,"
+1-"
+01"
+0."
+13"
+14"
+05"
+18"
+1:"
+1;"
+0<"
+0?"
+1A"
+1B"
+0C"
+1H"
+1I"
+0J"
+1O"
+1P"
+0Q"
+1V"
+1W"
+0X"
+1]"
+1b"
+1^"
+0_"
+1d"
+1e"
+0i"
+0f"
+1k"
+1l"
+0m"
+1p"
+1r"
+1s"
+0t"
+0w"
+1y"
+1z"
+0{"
+1"#
+1##
+0$#
+1)#
+1*#
+0+#
+10#
+11#
+02#
+17#
+1<#
+18#
+09#
+1>#
+1?#
+0C#
+0@#
+1E#
+1F#
+0G#
+1J#
+1L#
+1M#
+0N#
+0Q#
+1S#
+1T#
+0U#
+1Z#
+1[#
+0\#
+1a#
+1b#
+0c#
+1h#
+1i#
+0j#
+1o#
+1p#
+0q#
+1v#
+1w#
+0x#
+0{#
+b11100101111101011010010110110101 #
+b11100101111101011010010110110101 A
+b11100101111101011010010110110101 /$
+1}#
+1~#
+0!$
+1&$
+1'$
+0($
+b10110100 I$
+b1010010010110100 )
+b1010010010110100 A$
+b1010010010110100 N$
+b10 M$
+1+
+0@$
+05$
+b100 I
+b1100 J
+b11 F
+14
+1?
+#13800000000000000
+04
+0?
+#13850000000000000
+1.$
+1'
+b11110101 ?$
+b11110101 .
+b11110101 B$
+0G$
+1T$
+1@$
+b1 M$
+0+
+b11100101 H$
+b1110010110110100 )
+b1110010110110100 A$
+b1110010110110100 N$
+b10 Z$
+1-
+b1010010010110100 V$
+b11100100111101001010010010110100 ,
+b11100100111101001010010010110100 R$
+14
+1?
+#13900000000000000
+04
+0?
+#13950000000000000
+0.$
+03$
+0B
+0'
+0$
+0T$
+1G$
+b10100101 ?$
+b10100101 .
+b10100101 B$
+b1010010110110101 &
+b1010010110110101 -$
+b1010010110110101 7$
+b0 Z$
+0-
+b11110101 I$
+b1110010111110101 )
+b1110010111110101 A$
+b1110010111110101 N$
+b10 M$
+1+
+0@$
+15$
+14
+1?
+#14000000000000000
+04
+0?
+#14050000000000000
+13$
+1B
+1.$
+1$
+1'
+b10110101 ?$
+b10110101 .
+b10110101 B$
+0G$
+1@$
+b1 M$
+0+
+b10100101 H$
+b1010010111110101 )
+b1010010111110101 A$
+b1010010111110101 N$
+b1 Z$
+b1110010111110101 U$
+b11100101111101011010010010110100 ,
+b11100101111101011010010010110100 R$
+14
+1?
+#14100000000000000
+04
+0?
+#14150000000000000
+0.$
+03$
+0B
+0'
+0$
+1G$
+b11100110 ?$
+b11100110 .
+b11100110 B$
+b1110011011110110 &
+b1110011011110110 -$
+b1110011011110110 7$
+0K
+0P
+0R
+1W
+0Y
+0`
+0g
+0n
+0u
+0|
+0%"
+0*"
+0,"
+11"
+03"
+0:"
+0A"
+0H"
+0O"
+0V"
+0]"
+0b"
+0d"
+1i"
+0k"
+0r"
+0y"
+0"#
+0)#
+00#
+07#
+0<#
+0>#
+1C#
+b11100110111101101010011010110110 #
+b11100110111101101010011010110110 A
+b11100110111101101010011010110110 /$
+0E#
+0L#
+0S#
+0Z#
+0a#
+0h#
+0o#
+0v#
+0}#
+0&$
+b10110101 I$
+b1010010110110101 )
+b1010010110110101 A$
+b1010010110110101 N$
+b10 M$
+1+
+0@$
+05$
+b11 I
+b1101 J
+b10 F
+14
+1?
+#14200000000000000
+04
+0?
+#14250000000000000
+1.$
+1'
+b11110110 ?$
+b11110110 .
+b11110110 B$
+0G$
+1T$
+1@$
+b1 M$
+0+
+b11100110 H$
+b1110011010110101 )
+b1110011010110101 A$
+b1110011010110101 N$
+b10 Z$
+1-
+b1010010110110101 V$
+b11100101111101011010010110110101 ,
+b11100101111101011010010110110101 R$
+14
+1?
+#14300000000000000
+04
+0?
+#14350000000000000
+0.$
+03$
+0B
+0'
+0$
+0T$
+1G$
+b10100110 ?$
+b10100110 .
+b10100110 B$
+b1010011010110110 &
+b1010011010110110 -$
+b1010011010110110 7$
+b0 Z$
+0-
+b11110110 I$
+b1110011011110110 )
+b1110011011110110 A$
+b1110011011110110 N$
+b10 M$
+1+
+0@$
+15$
+14
+1?
+#14400000000000000
+04
+0?
+#14450000000000000
+13$
+1B
+1.$
+1$
+1'
+b10110110 ?$
+b10110110 .
+b10110110 B$
+0G$
+1@$
+b1 M$
+0+
+b10100110 H$
+b1010011011110110 )
+b1010011011110110 A$
+b1010011011110110 N$
+b1 Z$
+b1110011011110110 U$
+b11100110111101101010010110110101 ,
+b11100110111101101010010110110101 R$
+14
+1?
+#14500000000000000
+04
+0?
+#14550000000000000
+0.$
+03$
+0B
+0'
+0$
+1G$
+b11100111 ?$
+b11100111 .
+b11100111 B$
+b1110011111110111 &
+b1110011111110111 -$
+b1110011111110111 7$
+1K
+1P
+0L
+1R
+0S
+1W
+1Y
+0Z
+1^
+1`
+0a
+0e
+1g
+0h
+1n
+0o
+1u
+0v
+1|
+0}
+1%"
+1*"
+0&"
+1,"
+0-"
+11"
+13"
+04"
+18"
+1:"
+0;"
+0?"
+1A"
+0B"
+1H"
+0I"
+1O"
+0P"
+1V"
+0W"
+1]"
+1b"
+0^"
+1d"
+0e"
+1i"
+1k"
+0l"
+1p"
+1r"
+0s"
+0w"
+1y"
+0z"
+1"#
+0##
+1)#
+0*#
+10#
+01#
+17#
+1<#
+08#
+1>#
+0?#
+1C#
+1E#
+0F#
+1J#
+1L#
+0M#
+0Q#
+1S#
+0T#
+1Z#
+0[#
+1a#
+0b#
+1h#
+0i#
+1o#
+0p#
+1v#
+0w#
+0{#
+b11100111111101111010011110110111 #
+b11100111111101111010011110110111 A
+b11100111111101111010011110110111 /$
+1}#
+0~#
+1&$
+0'$
+b10110110 I$
+b1010011010110110 )
+b1010011010110110 A$
+b1010011010110110 N$
+b10 M$
+1+
+0@$
+05$
+b10 I
+b1110 J
+b1 F
+14
+1?
+#14600000000000000
+04
+0?
+#14650000000000000
+1.$
+1'
+b11110111 ?$
+b11110111 .
+b11110111 B$
+0G$
+1T$
+1@$
+b1 M$
+0+
+b11100111 H$
+b1110011110110110 )
+b1110011110110110 A$
+b1110011110110110 N$
+b10 Z$
+1-
+b1010011010110110 V$
+b11100110111101101010011010110110 ,
+b11100110111101101010011010110110 R$
+14
+1?
+#14700000000000000
+04
+0?
+#14750000000000000
+0.$
+03$
+0B
+0'
+0$
+0T$
+1G$
+b10100111 ?$
+b10100111 .
+b10100111 B$
+b1010011110110111 &
+b1010011110110111 -$
+b1010011110110111 7$
+b0 Z$
+0-
+b11110111 I$
+b1110011111110111 )
+b1110011111110111 A$
+b1110011111110111 N$
+b10 M$
+1+
+0@$
+15$
+14
+1?
+#14800000000000000
+04
+0?
+#14850000000000000
+13$
+1B
+1.$
+1$
+1'
+b10110111 ?$
+b10110111 .
+b10110111 B$
+0G$
+1@$
+b1 M$
+0+
+b10100111 H$
+b1010011111110111 )
+b1010011111110111 A$
+b1010011111110111 N$
+b1 Z$
+b1110011111110111 U$
+b11100111111101111010011010110110 ,
+b11100111111101111010011010110110 R$
+14
+1?
+#14900000000000000
+04
+0?
+#14950000000000000
+0.$
+03$
+0B
+0'
+0$
+10$
+1G$
+b11101000 ?$
+b11101000 .
+b11101000 B$
+b1110100011111000 &
+b1110100011111000 -$
+b1110100011111000 7$
+0K
+0P
+0R
+0W
+0Y
+0^
+0`
+1e
+0g
+0n
+0u
+0|
+0%"
+0*"
+0,"
+01"
+03"
+08"
+0:"
+1?"
+0A"
+0H"
+0O"
+0V"
+0]"
+0b"
+0d"
+0i"
+0k"
+0p"
+0r"
+1w"
+0y"
+0"#
+0)#
+00#
+07#
+0<#
+0>#
+0C#
+0E#
+0J#
+0L#
+1Q#
+0S#
+0Z#
+0a#
+0h#
+0o#
+0v#
+1{#
+b1011101000111110001010100010111000 #
+b1011101000111110001010100010111000 A
+b1011101000111110001010100010111000 /$
+0}#
+0&$
+b10110111 I$
+b1010011110110111 )
+b1010011110110111 A$
+b1010011110110111 N$
+b10 M$
+1+
+0@$
+05$
+b1 I
+b1111 J
+b0 F
+14
+1?
+#15000000000000000
+04
+0?
+#15050000000000000
+1.$
+1'
+b11111000 ?$
+b11111000 .
+b11111000 B$
+0G$
+1T$
+1@$
+b1 M$
+0+
+b11101000 H$
+b1110100010110111 )
+b1110100010110111 A$
+b1110100010110111 N$
+b10 Z$
+1-
+b1010011110110111 V$
+b11100111111101111010011110110111 ,
+b11100111111101111010011110110111 R$
+14
+1?
+#15100000000000000
+04
+0?
+#15150000000000000
+0.$
+03$
+0B
+0'
+18$
+0$
+0T$
+1G$
+b10101000 ?$
+b10101000 .
+b10101000 B$
+b101010100010111000 &
+b101010100010111000 -$
+b101010100010111000 7$
+b0 Z$
+0-
+b11111000 I$
+b1110100011111000 )
+b1110100011111000 A$
+b1110100011111000 N$
+b10 M$
+1+
+0@$
+15$
+14
+1?
+#15200000000000000
+04
+0?
+#15250000000000000
+1D$
+13$
+1B
+00
+1.$
+1$
+1<$
+1'
+b10111000 ?$
+b10111000 .
+b10111000 B$
+0G$
+1@$
+b1 M$
+0+
+b10101000 H$
+b1010100011111000 )
+b1010100011111000 A$
+b1010100011111000 N$
+b1 Z$
+b1110100011111000 U$
+b11101000111110001010011110110111 ,
+b11101000111110001010011110110111 R$
+14
+1?
+#15300000000000000
+04
+0?
+#15350000000000000
+0D$
+10
+0'
+0F$
+0<$
+08$
+0$
+0.$
+06$
+12
+03$
+0B
+1G$
+1O$
+b11101000 ?$
+b11101000 .
+b11101000 B$
+b1110100011111000 &
+b1110100011111000 -$
+b1110100011111000 7$
+0>$
+0(
+0%
+b10111000 I$
+b10 M$
+1+
+1J$
+b101010100010111000 )
+b101010100010111000 A$
+b101010100010111000 N$
+0@$
+05$
+b0 I
+b10000 J
+1G
+14
+1?
+#15400000000000000
+04
+0?
+#15450000000000000
+0G$
+1T$
+b0 M$
+0+
+1W$
+b10 Z$
+1-
+b1010100010111000 V$
+b1011101000111110001010100010111000 ,
+b1011101000111110001010100010111000 R$
+14
+1?
+#15500000000000000
+04
+0?
+#15550000000000000
+0T$
+b0 Z$
+0-
+14
+1?
+#15600000000000000
+04
+0?
+#15650000000000000
+14
+1?
+#15700000000000000
+04
+0?
+#15750000000000000
+14
+1?
+#15800000000000000
+04
+0?
+#15850000000000000
+14
+1?
+#15900000000000000
+04
+0?
+#15950000000000000
+14
+1?
+#16000000000000000
+04
+0?
+#16050000000000000
+14
+1?
+#16100000000000000
+04
+0?
+#16150000000000000
+14
+1?
+#16200000000000000
+04
+0?
+#16250000000000000
+14
+1?
+#16300000000000000
+04
+0?
+#16350000000000000
+14
+1?
+#16400000000000000
+04
+0?
+#16450000000000000
+14
+1?
+#16500000000000000
+04
+0?
+#16550000000000000
+14
+1?
+#16600000000000000
+04
+0?
+#16650000000000000
+14
+1?
+#16700000000000000
+04
+0?
+#16750000000000000
+14
+1?
+#16800000000000000
+04
+0?
+#16850000000000000
+14
+1?
+#16900000000000000
+04
+0?
+#16950000000000000
+14
+1?
+#17000000000000000
+04
+0?
+#17050000000000000
+14
+1?
+#17100000000000000
+04
+0?
+#17150000000000000
+14
+1?
+#17200000000000000
+04
+0?
+#17250000000000000
+14
+1?
+#17300000000000000
+04
+0?
+#17350000000000000
+14
+1?
+#17400000000000000
+04
+0?
+#17450000000000000
+14
+1?
+#17500000000000000
+04
+0?
+#17550000000000000
+14
+1?
+#17600000000000000
+04
+0?
+#17650000000000000
+14
+1?
+#17700000000000000
+04
+0?
+#17750000000000000
+14
+1?
+#17800000000000000
+04
+0?
+#17850000000000000
+14
+1?
+#17900000000000000
+04
+0?
+#17950000000000000
+14
+1?
+#18000000000000000
+04
+0?
+#18050000000000000
+14
+1?
+#18100000000000000
+04
+0?
+#18150000000000000
+14
+1?
+#18200000000000000
+04
+0?
+#18250000000000000
+14
+1?
+#18300000000000000
+04
+0?
+#18350000000000000
+14
+1?
+#18400000000000000
+04
+0?
+#18450000000000000
+14
+1?
+#18500000000000000
+04
+0?
+#18550000000000000
+14
+1?
+#18600000000000000
+04
+0?
+#18650000000000000
+14
+1?
+#18700000000000000
+04
+0?
+#18750000000000000
+14
+1?
+#18800000000000000
+04
+0?
+#18850000000000000
+14
+1?
+#18900000000000000
+04
+0?
+#18950000000000000
+14
+1?
+#19000000000000000
+04
+0?
+#19050000000000000
+14
+1?
+#19100000000000000
+04
+0?
+#19150000000000000
+14
+1?
+#19200000000000000
+04
+0?
+#19250000000000000
+14
+1?
+#19300000000000000
+04
+0?
+#19350000000000000
+14
+1?
+#19400000000000000
+04
+0?
+#19450000000000000
+14
+1?
+#19500000000000000
+04
+0?
+#19550000000000000
+14
+1?
+#19600000000000000
+04
+0?
+#19650000000000000
+14
+1?
+#19700000000000000
+04
+0?
+#19750000000000000
+14
+1?
+#19800000000000000
+04
+0?
+#19850000000000000
+14
+1?
+#19900000000000000
+04
+0?
+#19950000000000000
+14
+1?
+#20000000000000000
+04
+0?
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_short.v b/fpga/usrp2/control_lib/newfifo/fifo_short.v
new file mode 100644
index 000000000..53a7603c7
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo_short.v
@@ -0,0 +1,95 @@
+
+module fifo_short
+ #(parameter WIDTH=32)
+ (input clk, input reset, input clear,
+ input [WIDTH-1:0] datain,
+ input src_rdy_i,
+ output dst_rdy_o,
+ output [WIDTH-1:0] dataout,
+ output src_rdy_o,
+ input dst_rdy_i,
+
+ output reg [4:0] space,
+ output reg [4:0] occupied);
+
+ reg full, empty;
+ wire write = src_rdy_i & dst_rdy_o;
+ wire read = dst_rdy_i & src_rdy_o;
+
+ assign dst_rdy_o = ~full;
+ assign src_rdy_o = ~empty;
+
+ reg [3:0] a;
+ genvar i;
+
+ generate
+ for (i=0;i<WIDTH;i=i+1)
+ begin : gen_srl16
+ SRL16E
+ srl16e(.Q(dataout[i]),
+ .A0(a[0]),.A1(a[1]),.A2(a[2]),.A3(a[3]),
+ .CE(write),.CLK(clk),.D(datain[i]));
+ end
+ endgenerate
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ a <= 0;
+ empty <= 1;
+ full <= 0;
+ end
+ else if(clear)
+ begin
+ a <= 0;
+ empty <= 1;
+ full<= 0;
+ end
+ else if(read & ~write)
+ begin
+ full <= 0;
+ if(a==0)
+ empty <= 1;
+ else
+ a <= a - 1;
+ end
+ else if(write & ~read)
+ begin
+ empty <= 0;
+ if(~empty)
+ a <= a + 1;
+ if(a == 14)
+ full <= 1;
+ end
+
+ // NOTE will fail if you write into a full fifo or read from an empty one
+
+ //////////////////////////////////////////////////////////////
+ // space and occupied are used for diagnostics, not
+ // guaranteed correct
+
+ //assign space = full ? 0 : empty ? 16 : 15-a;
+ //assign occupied = empty ? 0 : full ? 16 : a+1;
+
+ always @(posedge clk)
+ if(reset)
+ space <= 16;
+ else if(clear)
+ space <= 16;
+ else if(read & ~write)
+ space <= space + 1;
+ else if(write & ~read)
+ space <= space - 1;
+
+ always @(posedge clk)
+ if(reset)
+ occupied <= 0;
+ else if(clear)
+ occupied <= 0;
+ else if(read & ~write)
+ occupied <= occupied - 1;
+ else if(write & ~read)
+ occupied <= occupied + 1;
+
+endmodule // fifo_short
+
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_spec.txt b/fpga/usrp2/control_lib/newfifo/fifo_spec.txt
new file mode 100644
index 000000000..133b9fa8e
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo_spec.txt
@@ -0,0 +1,36 @@
+
+
+FIFO and Buffer Interface Spec
+
+Buffer Interface Data Wires -- matches fifo36
+ DATA[31:0]
+ FLAGS[3:0]
+ Bit 0 SOP
+ Bit 1 EOP
+ If SOP=1 && EOP=1, OCC contains error flags
+ Bits 3:2 OCC[1:0] --> 00 = all 4 bytes
+ 01 = 1 byte
+ 10 = 2 bytes
+ 11 = 3 bytes
+
+fifo36 --> {OCC[1:0],EOP,SOP,DATA[31:0]}
+ OCC same as buffer interface
+
+fifo19 --> {OCC,EOP,SOP,DATA[15:0]}
+ Doesn't fit well into BRAM, dist RAM ok
+ OCC = 1 means last word is half full
+ = 0 means last word is full
+
+fifo18 --> {EOP,SOP,DATA[15:0]}
+ No half-word capability? Should we drop sop instead?
+
+Control Wires - Data into FIFO
+ SRC_RDY_i Upstream has data for me
+ DST_RDY_o I have space
+ Transfer occurs if SRC_RDI_i && DST_RDY_o
+
+Control Wires - Data out of FIFO
+ SRC_RDY_o I have data for downstream
+ DST_RDY_i Downstream has space
+ Transfer occurs if SRC_RDI_o && DST_RDY_i
+
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_tb.v b/fpga/usrp2/control_lib/newfifo/fifo_tb.v
new file mode 100644
index 000000000..f561df7fa
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/fifo_tb.v
@@ -0,0 +1,158 @@
+module fifo_new_tb();
+
+ reg clk = 0;
+ reg rst = 1;
+ reg clear = 0;
+ initial #1000 rst = 0;
+ always #50 clk = ~clk;
+
+ reg [31:0] f36_data = 0;
+ reg [1:0] f36_occ = 0;
+ reg f36_sof = 0, f36_eof = 0;
+
+ wire [35:0] f36_in = {f36_occ,f36_eof,f36_sof,f36_data};
+ reg src_rdy_f36i = 0;
+ wire dst_rdy_f36i;
+
+ wire [35:0] f36_out, f36_out2;
+ wire src_rdy_f36o;
+ reg dst_rdy_f36o = 0;
+
+ //fifo_cascade #(.WIDTH(36), .SIZE(4)) fifo_cascade36
+ //fifo_long #(.WIDTH(36), .SIZE(4)) fifo_cascade36
+
+ wire i1_sr, i1_dr;
+ wire i2_sr, i2_dr;
+ wire i3_sr, i3_dr;
+ reg i4_dr = 0;
+ wire i4_sr;
+
+ wire [35:0] i1, i4;
+ wire [18:0] i2, i3;
+
+ wire [7:0] ll_data;
+ wire ll_src_rdy_n, ll_dst_rdy_n, ll_sof_n, ll_eof_n;
+
+ fifo_short #(.WIDTH(36)) fifo_short1
+ (.clk(clk),.reset(rst),.clear(clear),
+ .datain(f36_in),.src_rdy_i(src_rdy_f36i),.dst_rdy_o(dst_rdy_f36i),
+ .dataout(i1),.src_rdy_o(i1_sr),.dst_rdy_i(i1_dr) );
+
+ fifo36_to_fifo19 fifo36_to_fifo19
+ (.clk(clk),.reset(rst),.clear(clear),
+ .f36_datain(i1),.f36_src_rdy_i(i1_sr),.f36_dst_rdy_o(i1_dr),
+ .f19_dataout(i2),.f19_src_rdy_o(i2_sr),.f19_dst_rdy_i(i2_dr) );
+
+ fifo19_to_ll8 fifo19_to_ll8
+ (.clk(clk),.reset(rst),.clear(clear),
+ .f19_data(i2),.f19_src_rdy_i(i2_sr),.f19_dst_rdy_o(i2_dr),
+ .ll_data(ll_data),.ll_sof_n(ll_sof_n),.ll_eof_n(ll_eof_n),
+ .ll_src_rdy_n(ll_src_rdy_n),.ll_dst_rdy_n(ll_dst_rdy_n));
+
+ ll8_to_fifo19 ll8_to_fifo19
+ (.clk(clk),.reset(rst),.clear(clear),
+ .ll_data(ll_data),.ll_sof_n(ll_sof_n),.ll_eof_n(ll_eof_n),
+ .ll_src_rdy_n(ll_src_rdy_n),.ll_dst_rdy_n(ll_dst_rdy_n),
+ .f19_data(i3),.f19_src_rdy_o(i3_sr),.f19_dst_rdy_i(i3_dr) );
+
+ fifo19_to_fifo36 fifo19_to_fifo36
+ (.clk(clk),.reset(rst),.clear(clear),
+ .f19_datain(i3),.f19_src_rdy_i(i3_sr),.f19_dst_rdy_o(i3_dr),
+ .f36_dataout(i4),.f36_src_rdy_o(i4_sr),.f36_dst_rdy_i(i4_dr) );
+
+ task ReadFromFIFO36;
+ begin
+ $display("Read from FIFO36");
+ #1 i4_dr <= 1;
+ while(1)
+ begin
+ while(~i4_sr)
+ @(posedge clk);
+ $display("Read: %h",i4);
+ @(posedge clk);
+ end
+ end
+ endtask // ReadFromFIFO36
+
+ 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("Put Packet in FIFO36");
+ while(~dst_rdy_f36i)
+ @(posedge clk);
+ @(posedge clk);
+ $display("PPI_FIFO36: Entered First Line");
+ f36_sof <= 0;
+ while(count+4 < data_len)
+ begin
+ f36_data <= f36_data + 32'h01010101;
+ count <= count + 4;
+ while(~dst_rdy_f36i)
+ @(posedge clk);
+ @(posedge clk);
+ $display("PPI_FIFO36: Entered New Line");
+ 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("PPI_FIFO36: Entered Last Line");
+ end
+ endtask // PutPacketInFIFO36
+
+ initial $dumpfile("fifo_new_tb.vcd");
+ initial $dumpvars(0,fifo_new_tb);
+
+ initial
+ begin
+ @(negedge rst);
+ //#10000;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ ReadFromFIFO36;
+ end
+
+ initial
+ begin
+ @(negedge rst);
+ @(posedge clk);
+ @(posedge clk);
+ PutPacketInFIFO36(32'hA0B0C0D0,12);
+ @(posedge clk);
+ @(posedge clk);
+ #10000;
+ @(posedge clk);
+ PutPacketInFIFO36(32'hE0F0A0B0,36);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ end
+
+ initial #20000 $finish;
+endmodule // longfifo_tb
diff --git a/fpga/usrp2/control_lib/newfifo/ll8_shortfifo.v b/fpga/usrp2/control_lib/newfifo/ll8_shortfifo.v
new file mode 100644
index 000000000..39ada9a4f
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/ll8_shortfifo.v
@@ -0,0 +1,13 @@
+
+
+module ll8_shortfifo
+ (input clk, input reset, input clear,
+ input [7:0] datain, input sof_i, input eof_i, input error_i, input src_rdy_i, output dst_rdy_o,
+ output [7:0] dataout, output sof_o, output eof_o, output error_o, output src_rdy_o, input dst_rdy_i);
+
+ fifo_short #(.WIDTH(11)) fifo_short
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain({error_i,eof_i,sof_i,datain}), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o),
+ .dataout({error_o,eof_o,sof_o,dataout}), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i));
+
+endmodule // ll8_shortfifo
diff --git a/fpga/usrp2/control_lib/newfifo/ll8_to_fifo19.v b/fpga/usrp2/control_lib/newfifo/ll8_to_fifo19.v
new file mode 100644
index 000000000..af3b91afb
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/ll8_to_fifo19.v
@@ -0,0 +1,73 @@
+
+module ll8_to_fifo19
+ (input clk, input reset, input clear,
+ input [7:0] ll_data,
+ input ll_sof_n,
+ input ll_eof_n,
+ input ll_src_rdy_n,
+ output ll_dst_rdy_n,
+
+ output [18:0] f19_data,
+ output f19_src_rdy_o,
+ input f19_dst_rdy_i );
+
+ localparam XFER_EMPTY = 0;
+ localparam XFER_HALF = 1;
+ localparam XFER_HALF_WRITE = 3;
+
+ // Why anybody would use active low in an FPGA is beyond me...
+ wire ll_sof = ~ll_sof_n;
+ wire ll_eof = ~ll_eof_n;
+ wire ll_src_rdy = ~ll_src_rdy_n;
+ wire ll_dst_rdy;
+ assign ll_dst_rdy_n = ~ll_dst_rdy;
+
+ wire xfer_out = f19_src_rdy_o & f19_dst_rdy_i;
+ wire xfer_in = ll_src_rdy & ll_dst_rdy;
+
+ reg hold_sof;
+ wire f19_sof, f19_eof, f19_occ;
+
+ reg [1:0] state;
+ reg [7:0] hold_reg;
+
+ always @(posedge clk)
+ if(ll_src_rdy & (state==XFER_EMPTY))
+ hold_reg <= ll_data;
+
+ always @(posedge clk)
+ if(ll_sof & (state==XFER_EMPTY))
+ hold_sof <= 1;
+ else if(xfer_out)
+ hold_sof <= 0;
+
+ always @(posedge clk)
+ if(reset | clear)
+ state <= XFER_EMPTY;
+ else
+ case(state)
+ XFER_EMPTY :
+ if(ll_src_rdy)
+ if(ll_eof)
+ state <= XFER_HALF_WRITE;
+ else
+ state <= XFER_HALF;
+ XFER_HALF :
+ if(ll_src_rdy & f19_dst_rdy_i)
+ state <= XFER_EMPTY;
+ XFER_HALF_WRITE :
+ if(f19_dst_rdy_i)
+ state <= XFER_EMPTY;
+ endcase // case (state)
+
+ assign ll_dst_rdy = (state==XFER_EMPTY) | ((state==XFER_HALF)&f19_dst_rdy_i);
+ assign f19_src_rdy_o = (state==XFER_HALF_WRITE) | ((state==XFER_HALF)&ll_src_rdy);
+
+ assign f19_sof = hold_sof | (ll_sof & (state==XFER_HALF));
+ assign f19_eof = (state == XFER_HALF_WRITE) | ll_eof;
+ assign f19_occ = (state == XFER_HALF_WRITE);
+
+ assign f19_data = {f19_occ,f19_eof,f19_sof,hold_reg,ll_data};
+
+endmodule // ll8_to_fifo19
+
diff --git a/fpga/usrp2/control_lib/newfifo/ll8_to_fifo36.v b/fpga/usrp2/control_lib/newfifo/ll8_to_fifo36.v
new file mode 100644
index 000000000..108daa903
--- /dev/null
+++ b/fpga/usrp2/control_lib/newfifo/ll8_to_fifo36.v
@@ -0,0 +1,97 @@
+
+module ll8_to_fifo36
+ (input clk, input reset, input clear,
+ input [7:0] ll_data,
+ input ll_sof_n,
+ input ll_eof_n,
+ input ll_src_rdy_n,
+ output ll_dst_rdy_n,
+
+ output [35:0] f36_data,
+ output f36_src_rdy_o,
+ input f36_dst_rdy_i );
+
+ wire f36_write = f36_src_rdy_o & f36_dst_rdy_i;
+
+ // Why anybody would use active low in an FPGA is beyond me...
+ wire ll_sof = ~ll_sof_n;
+ wire ll_eof = ~ll_eof_n;
+ wire ll_src_rdy = ~ll_src_rdy_n;
+ wire ll_dst_rdy;
+ assign ll_dst_rdy_n = ~ll_dst_rdy;
+
+ reg f36_sof, f36_eof;
+ reg [1:0] f36_occ;
+
+
+ reg [2:0] state;
+ reg [7:0] dat0, dat1, dat2, dat3;
+
+ always @(posedge clk)
+ if(ll_src_rdy & ((state==0)|f36_write))
+ f36_sof <= ll_sof;
+
+ always @(posedge clk)
+ if(ll_src_rdy & ((state !=4)|f36_write))
+ f36_eof <= ll_eof;
+
+ always @(posedge clk)
+ if(ll_eof)
+ f36_occ <= state[1:0] + 1;
+ else
+ f36_occ <= 0;
+
+ always @(posedge clk)
+ if(reset)
+ state <= 0;
+ else
+ if(ll_src_rdy)
+ case(state)
+ 0 :
+ if(ll_eof)
+ state <= 4;
+ else
+ state <= 1;
+ 1 :
+ if(ll_eof)
+ state <= 4;
+ else
+ state <= 2;
+ 2 :
+ if(ll_eof)
+ state <= 4;
+ else
+ state <= 3;
+ 3 : state <= 4;
+ 4 :
+ if(f36_dst_rdy_i)
+ if(ll_eof)
+ state <= 4;
+ else
+ state <= 1;
+ endcase // case(state)
+ else
+ if(f36_write)
+ state <= 0;
+
+ always @(posedge clk)
+ if(ll_src_rdy & (state==3))
+ dat3 <= ll_data;
+
+ always @(posedge clk)
+ if(ll_src_rdy & (state==2))
+ dat2 <= ll_data;
+
+ always @(posedge clk)
+ if(ll_src_rdy & (state==1))
+ dat1 <= ll_data;
+
+ always @(posedge clk)
+ if(ll_src_rdy & ((state==0) | f36_write))
+ dat0 <= ll_data;
+
+ assign ll_dst_rdy = f36_dst_rdy_i | (state != 4);
+ assign f36_data = {f36_occ,f36_eof,f36_sof,dat0,dat1,dat2,dat3}; // FIXME endianess
+ assign f36_src_rdy_o = (state == 4);
+
+endmodule // ll8_to_fifo36
diff --git a/fpga/usrp2/control_lib/nsgpio.v b/fpga/usrp2/control_lib/nsgpio.v
new file mode 100644
index 000000000..937ea7020
--- /dev/null
+++ b/fpga/usrp2/control_lib/nsgpio.v
@@ -0,0 +1,107 @@
+// Modified from code originally by Richard Herveille, his copyright is below
+
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// OpenCores Simple General Purpose IO core ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+
+module nsgpio
+ (input clk_i, input rst_i,
+ input cyc_i, input stb_i, input [3:0] adr_i, input we_i, input [31:0] dat_i,
+ output reg [31:0] dat_o, output reg ack_o,
+ input [31:0] atr, input [31:0] debug_0, input [31:0] debug_1,
+ inout [31:0] gpio
+ );
+
+ reg [63:0] ctrl;
+ reg [31:0] line;
+ reg [31:0] lgpio; // LatchedGPIO pins
+ reg [31:0] ddr;
+
+ wire wb_acc = cyc_i & stb_i; // WISHBONE access
+ wire wb_wr = wb_acc & we_i; // WISHBONE write access
+
+ always @(posedge clk_i or posedge rst_i)
+ if (rst_i)
+ begin
+ ctrl <= 64'h0;
+ line <= 0;
+ end
+ else if (wb_wr)
+ case( adr_i[3:2] )
+ 2'b00 :
+ line <= dat_i;
+ 2'b01 :
+ ddr[31:0] <= dat_i;
+ 2'b10 :
+ ctrl[63:32] <= dat_i;
+ 2'b11 :
+ ctrl[31:0] <= dat_i;
+ endcase // case( adr_i[3:2] )
+
+ always @(posedge clk_i)
+ case (adr_i[3:2])
+ 2'b00 :
+ dat_o <= lgpio;
+ 2'b01 :
+ dat_o <= ddr;
+ 2'b10 :
+ dat_o <= ctrl[63:32];
+ 2'b11 :
+ dat_o <= ctrl[31:0];
+ endcase // case(adr_i[3:2])
+
+ always @(posedge clk_i or posedge rst_i)
+ if (rst_i)
+ ack_o <= 1'b0;
+ else
+ ack_o <= wb_acc & !ack_o;
+
+ // latch GPIO input pins
+ always @(posedge clk_i)
+ lgpio <= gpio;
+
+ // assign GPIO outputs
+ integer n;
+ reg [31:0] igpio; // temporary internal signal
+
+ always @(ctrl or line or debug_1 or debug_0 or atr)
+ for(n=0;n<32;n=n+1)
+ igpio[n] <= ddr[n] ? (ctrl[2*n+1] ? (ctrl[2*n] ? debug_1[n] : debug_0[n]) :
+ (ctrl[2*n] ? atr[n] : line[n]) )
+ : 1'bz;
+
+ assign gpio = igpio;
+
+endmodule
+
diff --git a/fpga/usrp2/control_lib/oneshot_2clk.v b/fpga/usrp2/control_lib/oneshot_2clk.v
new file mode 100644
index 000000000..72f16a4b3
--- /dev/null
+++ b/fpga/usrp2/control_lib/oneshot_2clk.v
@@ -0,0 +1,35 @@
+
+// Retime a single bit from one clock domain to another
+// Guarantees that no matter what the relative clock rates, if the in signal is high for at least
+// one clock cycle in the clk_in domain, then the out signal will be high for at least one
+// clock cycle in the clk_out domain. If the in signal goes high again before the process is done
+// the behavior is undefined. No other guarantees. Designed for passing reset into a new
+// clock domain.
+
+module oneshot_2clk
+ (input clk_in,
+ input in,
+ input clk_out,
+ output reg out);
+
+ reg del_in = 0;
+ reg sendit = 0, gotit = 0;
+ reg sendit_d = 0, gotit_d = 0;
+
+ always @(posedge clk_in) del_in <= in;
+
+ always @(posedge clk_in)
+ if(in & ~del_in) // we have a positive edge
+ sendit <= 1;
+ else if(gotit)
+ sendit <= 0;
+
+ always @(posedge clk_out) sendit_d <= sendit;
+ always @(posedge clk_out) out <= sendit_d;
+
+ always @(posedge clk_in) gotit_d <= out;
+ always @(posedge clk_in) gotit <= gotit_d;
+
+endmodule // oneshot_2clk
+
+
diff --git a/fpga/usrp2/control_lib/pic.v b/fpga/usrp2/control_lib/pic.v
new file mode 100644
index 000000000..9b9944d4a
--- /dev/null
+++ b/fpga/usrp2/control_lib/pic.v
@@ -0,0 +1,183 @@
+
+// Heavily modified by M. Ettus, 2009, little original code remains
+// Modified by M. Ettus, 2008 for 32 bit width
+
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// OpenCores Simple Programmable Interrupt Controller ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//
+// This is a simple Programmable Interrupt Controller.
+// The number of interrupts is depending on the databus size.
+// There's one interrupt input per databit (i.e. 16 interrupts for a 16
+// bit databus).
+// All attached devices share the same CPU priority level.
+//
+//
+//
+// Registers:
+//
+// 0x00: EdgeEnable Register
+// bits 7:0 R/W Edge Enable '1' = edge triggered interrupt source
+// '0' = level triggered interrupt source
+// 0x01: PolarityRegister
+// bits 7:0 R/W Polarity '1' = high level / rising edge
+// '0' = low level / falling edge
+// 0x02: MaskRegister
+// bits 7:0 R/W Mask '1' = interrupt masked (disabled)
+// '0' = interrupt not masked (enabled)
+// 0x03: PendingRegister
+// bits 7:0 R/W Pending '1' = interrupt pending
+// '0' = no interrupt pending
+//
+// A CPU interrupt is generated when an interrupt is pending and its
+// MASK bit is cleared.
+//
+//
+//
+// HOWTO:
+//
+// Clearing pending interrupts:
+// Writing a '1' to a bit in the interrupt pending register clears the
+// interrupt. Make sure to clear the interrupt at the source before
+// writing to the interrupt pending register. Otherwise the interrupt
+// will be set again.
+//
+// Priority based interrupts:
+// Upon reception of an interrupt, check the interrupt register and
+// determine the highest priority interrupt. Mask all interrupts from the
+// current level to the lowest level. This negates the interrupt line, and
+// makes sure only interrupts with a higher level are triggered. After
+// completion of the interrupt service routine, clear the interrupt source,
+// the interrupt bit in the pending register, and restore the MASK register
+// to it's previous state.
+//
+// Addapt the core for fewer interrupt sources:
+// If less than 8 interrupt sources are required, than the 'is' parameter
+// can be set to the amount of required interrupts. Interrupts are mapped
+// starting at the LSBs. So only the 'is' LSBs per register are valid. All
+// other bits (i.e. the 8-'is' MSBs) are set to zero '0'.
+// Codesize is approximately linear to the amount of interrupts. I.e. using
+// 4 instead of 8 interrupt sources reduces the size by approx. half.
+//
+
+
+module pic
+ (input clk_i, input rst_i, input cyc_i, input stb_i,
+ input [2:0] adr_i,
+ input we_i,
+ input [31:0] dat_i,
+ output reg [31:0] dat_o,
+ output reg ack_o,
+ output reg int_o,
+ input [31:0] irq
+ );
+
+ reg [31:0] pol, edgen, pending, mask; // register bank
+ reg [31:0] lirq, dirq; // latched irqs, delayed latched irqs
+
+ // latch interrupt inputs
+ always @(posedge clk_i)
+ lirq <= irq;
+
+ // generate delayed latched irqs
+ always @(posedge clk_i)
+ dirq <= lirq;
+
+ // generate actual triggers
+ function trigger;
+ input edgen, pol, lirq, dirq;
+ reg edge_irq, level_irq;
+ begin
+ edge_irq = pol ? (lirq & ~dirq) : (dirq & ~lirq);
+ level_irq = pol ? lirq : ~lirq;
+ trigger = edgen ? edge_irq : level_irq;
+ end
+ endfunction
+
+ reg [31:0] irq_event;
+ integer n;
+ always @(posedge clk_i)
+ for(n = 0; n < 32; n = n+1)
+ irq_event[n] <= trigger(edgen[n], pol[n], lirq[n], dirq[n]);
+
+ // generate wishbone register bank writes
+ wire wb_acc = cyc_i & stb_i; // WISHBONE access
+ wire wb_wr = wb_acc & we_i; // WISHBONE write access
+
+ always @(posedge clk_i)
+ if (rst_i)
+ begin
+ pol <= 0; // clear polarity register
+ edgen <= 0; // clear edge enable register
+ mask <= 0; // mask all interrupts
+ end
+ else if(wb_wr) // wishbone write cycle??
+ case (adr_i) // synopsys full_case parallel_case
+ 3'd0 : edgen <= dat_i; // EDGE-ENABLE register
+ 3'd1 : pol <= dat_i; // POLARITY register
+ 3'd2 : mask <= dat_i; // MASK register
+ 3'd3 : ; // PENDING register is a special case (see below)
+ 3'd4 : ; // Priority encoded live (pending & ~mask)
+ endcase
+
+ // pending register is a special case
+ always @(posedge clk_i)
+ if (rst_i)
+ pending <= 0; // clear all pending interrupts
+ else if ( wb_wr & (adr_i == 3'd3) )
+ pending <= (pending & ~dat_i) | irq_event;
+ else
+ pending <= pending | irq_event;
+
+ wire [31:0] live_enc;
+ priority_enc priority_enc ( .in(pending & ~mask), .out(live_enc) );
+
+ always @(posedge clk_i)
+ case (adr_i) // synopsys full_case parallel_case
+ 3'd0 : dat_o <= edgen;
+ 3'd1 : dat_o <= pol;
+ 3'd2 : dat_o <= mask;
+ 3'd3 : dat_o <= pending;
+ 3'd4 : dat_o <= live_enc;
+ endcase
+
+ always @(posedge clk_i)
+ ack_o <= wb_acc & !ack_o;
+
+ always @(posedge clk_i)
+ if(rst_i)
+ int_o <= 0;
+ else
+ int_o <= |(pending & ~mask);
+
+endmodule
diff --git a/fpga/usrp2/control_lib/priority_enc.v b/fpga/usrp2/control_lib/priority_enc.v
new file mode 100644
index 000000000..916192445
--- /dev/null
+++ b/fpga/usrp2/control_lib/priority_enc.v
@@ -0,0 +1,44 @@
+
+module priority_enc
+ (input [31:0] in,
+ output reg [31:0] out);
+
+ always @*
+ casex(in)
+ 32'b1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 31;
+ 32'b01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 30;
+ 32'b001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 29;
+ 32'b0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 28;
+ 32'b0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 27;
+ 32'b0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 26;
+ 32'b0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 25;
+ 32'b0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 24;
+ 32'b0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 23;
+ 32'b0000_0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 22;
+ 32'b0000_0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 21;
+ 32'b0000_0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx : out <= 20;
+ 32'b0000_0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx : out <= 19;
+ 32'b0000_0000_0000_01xx_xxxx_xxxx_xxxx_xxxx : out <= 18;
+ 32'b0000_0000_0000_001x_xxxx_xxxx_xxxx_xxxx : out <= 17;
+ 32'b0000_0000_0000_0001_xxxx_xxxx_xxxx_xxxx : out <= 16;
+ 32'b0000_0000_0000_0000_1xxx_xxxx_xxxx_xxxx : out <= 15;
+ 32'b0000_0000_0000_0000_01xx_xxxx_xxxx_xxxx : out <= 14;
+ 32'b0000_0000_0000_0000_001x_xxxx_xxxx_xxxx : out <= 13;
+ 32'b0000_0000_0000_0000_0001_xxxx_xxxx_xxxx : out <= 12;
+ 32'b0000_0000_0000_0000_0000_1xxx_xxxx_xxxx : out <= 11;
+ 32'b0000_0000_0000_0000_0000_01xx_xxxx_xxxx : out <= 10;
+ 32'b0000_0000_0000_0000_0000_001x_xxxx_xxxx : out <= 9;
+ 32'b0000_0000_0000_0000_0000_0001_xxxx_xxxx : out <= 8;
+ 32'b0000_0000_0000_0000_0000_0000_1xxx_xxxx : out <= 7;
+ 32'b0000_0000_0000_0000_0000_0000_01xx_xxxx : out <= 6;
+ 32'b0000_0000_0000_0000_0000_0000_001x_xxxx : out <= 5;
+ 32'b0000_0000_0000_0000_0000_0000_0001_xxxx : out <= 4;
+ 32'b0000_0000_0000_0000_0000_0000_0000_1xxx : out <= 3;
+ 32'b0000_0000_0000_0000_0000_0000_0000_01xx : out <= 2;
+ 32'b0000_0000_0000_0000_0000_0000_0000_001x : out <= 1;
+ 32'b0000_0000_0000_0000_0000_0000_0000_0001 : out <= 0;
+ 32'b0000_0000_0000_0000_0000_0000_0000_0000 : out <= 32'hFFFF_FFFF;
+ default : out <= 32'hFFFF_FFFF;
+ endcase // casex (in)
+
+endmodule // priority_enc
diff --git a/fpga/usrp2/control_lib/ram_2port.v b/fpga/usrp2/control_lib/ram_2port.v
new file mode 100644
index 000000000..3716a7c8a
--- /dev/null
+++ b/fpga/usrp2/control_lib/ram_2port.v
@@ -0,0 +1,42 @@
+
+
+module ram_2port
+ #(parameter DWIDTH=32,
+ parameter AWIDTH=9)
+ (input clka,
+ input ena,
+ input wea,
+ input [AWIDTH-1:0] addra,
+ input [DWIDTH-1:0] dia,
+ output reg [DWIDTH-1:0] doa,
+
+ input clkb,
+ input enb,
+ input web,
+ input [AWIDTH-1:0] addrb,
+ input [DWIDTH-1:0] dib,
+ output reg [DWIDTH-1:0] dob);
+
+ reg [DWIDTH-1:0] ram [(1<<AWIDTH)-1:0];
+ integer i;
+ initial
+ for(i=0;i<(1<<AWIDTH);i=i+1)
+ ram[i] <= {DWIDTH{1'b0}};
+
+ always @(posedge clka) begin
+ if (ena)
+ begin
+ if (wea)
+ ram[addra] <= dia;
+ doa <= ram[addra];
+ end
+ end
+ always @(posedge clkb) begin
+ if (enb)
+ begin
+ if (web)
+ ram[addrb] <= dib;
+ dob <= ram[addrb];
+ end
+ end
+endmodule // ram_2port
diff --git a/fpga/usrp2/control_lib/ram_harv_cache.v b/fpga/usrp2/control_lib/ram_harv_cache.v
new file mode 100644
index 000000000..29fdebf7a
--- /dev/null
+++ b/fpga/usrp2/control_lib/ram_harv_cache.v
@@ -0,0 +1,75 @@
+
+
+// Dual ported, Harvard architecture, cached ram
+
+module ram_harv_cache
+ #(parameter AWIDTH=15,parameter RAM_SIZE=16384,parameter ICWIDTH=6,parameter DCWIDTH=6)
+ (input wb_clk_i, input wb_rst_i,
+
+ input [AWIDTH-1:0] ram_loader_adr_i,
+ input [31:0] ram_loader_dat_i,
+ input ram_loader_stb_i,
+ input [3:0] ram_loader_sel_i,
+ input ram_loader_we_i,
+ output ram_loader_ack_o,
+ input ram_loader_done_i,
+
+ input [AWIDTH-1:0] iwb_adr_i,
+ input iwb_stb_i,
+ output [31:0] iwb_dat_o,
+ output iwb_ack_o,
+
+ input [AWIDTH-1:0] dwb_adr_i,
+ input [31:0] dwb_dat_i,
+ output [31:0] dwb_dat_o,
+ input dwb_we_i,
+ output dwb_ack_o,
+ input dwb_stb_i,
+ input [3:0] dwb_sel_i,
+
+ input flush_icache );
+
+ wire [31:0] iram_dat, dram_dat_i, dram_dat_o;
+ wire [AWIDTH-1:0] iram_adr, dram_adr;
+ wire iram_en, dram_en, dram_we;
+ wire [3:0] dram_sel;
+
+ dpram32 #(.AWIDTH(AWIDTH),.RAM_SIZE(RAM_SIZE)) sys_ram
+ (.clk(wb_clk_i),
+
+ .adr1_i(ram_loader_done_i ? iram_adr : ram_loader_adr_i),
+ .dat1_i(ram_loader_dat_i),
+ .dat1_o(iram_dat),
+ .we1_i(ram_loader_done_i ? 1'b0 : ram_loader_we_i),
+ .en1_i(ram_loader_done_i ? iram_en : ram_loader_stb_i),
+ .sel1_i(ram_loader_done_i ? 4'hF : ram_loader_sel_i),
+
+ .adr2_i(dram_adr),.dat2_i(dram_dat_i),.dat2_o(dram_dat_o),
+ .we2_i(dram_we),.en2_i(dram_en),.sel2_i(dram_sel) );
+
+ // Data bus side
+ dcache #(.AWIDTH(AWIDTH),.CWIDTH(DCWIDTH))
+ dcache(.wb_clk_i(wb_clk_i),.wb_rst_i(wb_rst_i),
+ .dwb_adr_i(dwb_adr_i),.dwb_stb_i(dwb_stb_i),
+ .dwb_we_i(dwb_we_i),.dwb_sel_i(dwb_sel_i),
+ .dwb_dat_i(dwb_dat_i),.dwb_dat_o(dwb_dat_o),
+ .dwb_ack_o(dwb_ack_o),
+ .dram_dat_i(dram_dat_o),.dram_dat_o(dram_dat_i),.dram_adr_o(dram_adr),
+ .dram_we_o(dram_we),.dram_en_o(dram_en), .dram_sel_o(dram_sel) );
+
+ // Instruction bus side
+ icache #(.AWIDTH(AWIDTH),.CWIDTH(ICWIDTH))
+ icache(.wb_clk_i(wb_clk_i),.wb_rst_i(wb_rst_i),
+ .iwb_adr_i(iwb_adr_i),.iwb_stb_i(iwb_stb_i),
+ .iwb_dat_o(iwb_dat_o),.iwb_ack_o(iwb_ack_o),
+ .iram_dat_i(iram_dat),.iram_adr_o(iram_adr),.iram_en_o(iram_en),
+ .flush(flush_icache));
+
+ // RAM loader
+ assign ram_loader_ack_o = ram_loader_stb_i;
+
+ // Performance Monitoring
+ wire i_wait = iwb_stb_i & ~iwb_ack_o;
+ wire d_wait = dwb_stb_i & ~dwb_ack_o;
+
+endmodule // ram_harv_cache
diff --git a/fpga/usrp2/control_lib/ram_loader.v b/fpga/usrp2/control_lib/ram_loader.v
new file mode 100644
index 000000000..cb67de739
--- /dev/null
+++ b/fpga/usrp2/control_lib/ram_loader.v
@@ -0,0 +1,225 @@
+
+// Adapted from VHDL code in spi_boot by Arnim Legauer
+// Added a full wishbone master interface (32-bit)
+
+module ram_loader #(parameter AWIDTH=16, RAM_SIZE=16384)
+ (input clk_i, input rst_i,
+ // CPLD Interface
+ input cfg_clk_i, input cfg_data_i,
+ output start_o, output mode_o, output done_o,
+ input detached_i,
+ // Wishbone interface
+ output wire [31:0] wb_dat_o,
+ output reg [AWIDTH-1:0] wb_adr_o,
+ output wb_stb_o,
+ output wb_cyc_o,
+ output reg [3:0] wb_sel_o,
+ output reg wb_we_o,
+ input wb_ack_i,
+ output ram_loader_done_o);
+
+ // FSM to control start signal, clocked on main clock
+ localparam FSM1_WAIT_DETACH = 2'b00;
+ localparam FSM1_CHECK_NO_DONE = 2'b01;
+ localparam FSM1_WAIT_DONE = 2'b10;
+
+ reg [1:0] start_fsm_q, start_fsm_s;
+ reg start_q, enable_q, start_s, enable_s;
+ reg done_q, done_s;
+
+ always @(posedge clk_i or posedge rst_i)
+ if(rst_i)
+ begin
+ start_fsm_q <= FSM1_WAIT_DETACH;
+ start_q <= 1'b0;
+ enable_q <= 1'b0;
+ end
+ else
+ begin
+ start_fsm_q <= start_fsm_s;
+ enable_q <= enable_s;
+ start_q <= start_s;
+ end // else: !if(rst_i)
+
+ always @*
+ case(start_fsm_q)
+ FSM1_WAIT_DETACH:
+ if(detached_i == 1'b1)
+ begin
+ start_fsm_s <= FSM1_CHECK_NO_DONE;
+ enable_s <= 1'b1;
+ start_s <= 1'b1;
+ end
+ else
+ begin
+ start_fsm_s <= FSM1_WAIT_DETACH;
+ enable_s <= enable_q;
+ start_s <= start_q;
+ end // else: !if(detached_i == 1'b1)
+ FSM1_CHECK_NO_DONE:
+ if(~done_q)
+ begin
+ start_fsm_s <= FSM1_WAIT_DONE;
+ enable_s <= enable_q;
+ start_s <= start_q;
+ end
+ else
+ begin
+ start_fsm_s <= FSM1_CHECK_NO_DONE;
+ enable_s <= enable_q;
+ start_s <= start_q;
+ end // else: !if(~done_q)
+ FSM1_WAIT_DONE:
+ if(done_q)
+ begin
+ start_fsm_s <= FSM1_WAIT_DETACH;
+ enable_s <= 1'b0;
+ start_s <= 1'b0;
+ end
+ else
+ begin
+ start_fsm_s <= FSM1_WAIT_DONE;
+ enable_s <= enable_q;
+ start_s <= start_q;
+ end // else: !if(done_q)
+ default:
+ begin
+ start_fsm_s <= FSM1_WAIT_DETACH;
+ enable_s <= enable_q;
+ start_s <= start_q;
+ end // else: !if(done_q)
+ endcase // case(start_fsm_q)
+
+ // FSM running on data clock
+
+ localparam FSM2_IDLE = 3'b000;
+ localparam FSM2_WE_ON = 3'b001;
+ localparam FSM2_WE_OFF = 3'b010;
+ localparam FSM2_INC_ADDR1 = 3'b011;
+ localparam FSM2_INC_ADDR2 = 3'b100;
+ localparam FSM2_FINISHED = 3'b101;
+
+ reg [AWIDTH-1:0] addr_q;
+ reg [7:0] shift_dat_q, ser_dat_q;
+ reg [2:0] bit_q, fsm_q, fsm_s;
+ reg bit_ovfl_q, ram_we_s, ram_we_q, mode_q, mode_s, inc_addr_s;
+
+ always @(posedge cfg_clk_i or posedge rst_i)
+ if(rst_i)
+ begin
+ addr_q <= 0;
+ shift_dat_q <= 8'd0;
+ ser_dat_q <= 8'd0;
+ bit_q <= 3'd0;
+ bit_ovfl_q <= 1'b0;
+ fsm_q <= FSM2_IDLE;
+ ram_we_q <= 1'b0;
+ done_q <= 1'b0;
+ mode_q <= 1'b0;
+ end
+ else
+ begin
+ if(inc_addr_s)
+ addr_q <= addr_q + 1;
+ if(enable_q)
+ begin
+ bit_q <= bit_q + 1;
+ bit_ovfl_q <= (bit_q == 3'd7);
+ shift_dat_q[0] <= cfg_data_i;
+ shift_dat_q[7:1] <= shift_dat_q[6:0];
+ end
+ if(bit_ovfl_q)
+ ser_dat_q <= shift_dat_q;
+
+ fsm_q <= fsm_s;
+
+ ram_we_q <= ram_we_s;
+
+ if(done_s)
+ done_q <= 1'b1;
+ mode_q <= mode_s;
+ end // else: !if(rst_i)
+
+ always @*
+ begin
+ inc_addr_s <= 1'b0;
+ ram_we_s <= 1'b0;
+ done_s <= 1'b0;
+ fsm_s <= FSM2_IDLE;
+ mode_s <= 1'b0;
+
+ case(fsm_q)
+ FSM2_IDLE :
+ if(start_q)
+ if(bit_ovfl_q)
+ fsm_s <= FSM2_WE_ON;
+ FSM2_WE_ON:
+ begin
+ ram_we_s <= 1'b1;
+ fsm_s <= FSM2_WE_OFF;
+ end
+ FSM2_WE_OFF:
+ begin
+ ram_we_s <= 1'b1;
+ fsm_s <= FSM2_INC_ADDR1;
+ end
+ FSM2_INC_ADDR1:
+ fsm_s <= FSM2_INC_ADDR2;
+ FSM2_INC_ADDR2:
+ if(addr_q == (RAM_SIZE-1))
+ //if(&addr_q)
+ begin
+ fsm_s <= FSM2_FINISHED;
+ done_s <= 1'b1;
+ mode_s <= 1'b1;
+ end
+ else
+ begin
+ inc_addr_s <= 1'b1;
+ fsm_s <= FSM2_IDLE;
+ end // else: !if(&addr_q)
+ FSM2_FINISHED:
+ begin
+ fsm_s <= FSM2_FINISHED;
+ mode_s <= 1'b1;
+ end
+ endcase // case(fsm_q)
+ end // always @ *
+
+ assign start_o = start_q;
+ assign mode_o = mode_q;
+ assign done_o = start_q ? done_q : 1'b1;
+ wire [AWIDTH-1:0] ram_addr = addr_q;
+ wire [7:0] ram_data = ser_dat_q;
+ assign ram_loader_done_o = (fsm_q == FSM2_FINISHED);
+
+ // wishbone master, only writes
+ reg [7:0] dat_holder;
+ assign wb_dat_o = {4{dat_holder}};
+ assign wb_stb_o = wb_we_o;
+ assign wb_cyc_o = wb_we_o;
+
+ always @(posedge clk_i or posedge rst_i)
+ if(rst_i)
+ begin
+ dat_holder <= 8'd0;
+ wb_adr_o <= 0;
+ wb_sel_o <= 4'b0000;
+ wb_we_o <= 1'b0;
+ end
+ else if(ram_we_q)
+ begin
+ dat_holder <= ram_data;
+ wb_adr_o <= ram_addr;
+ wb_we_o <= 1'b1;
+ case(ram_addr[1:0]) // Big Endian
+ 2'b00 : wb_sel_o <= 4'b1000;
+ 2'b01 : wb_sel_o <= 4'b0100;
+ 2'b10 : wb_sel_o <= 4'b0010;
+ 2'b11 : wb_sel_o <= 4'b0001;
+ endcase // case(ram_addr[1:0])
+ end // if (ram_we_q)
+ else if(wb_ack_i)
+ wb_we_o <= 1'b0;
+
+endmodule // ram_loader
diff --git a/fpga/usrp2/control_lib/ram_wb_harvard.v b/fpga/usrp2/control_lib/ram_wb_harvard.v
new file mode 100644
index 000000000..c3efc12e0
--- /dev/null
+++ b/fpga/usrp2/control_lib/ram_wb_harvard.v
@@ -0,0 +1,86 @@
+
+// Dual ported RAM for Harvard architecture processors
+// Does no forwarding
+// Addresses are byte-oriented, so botton 2 address bits are ignored. FIXME
+// AWIDTH of 13 gives 8K bytes. For Spartan 3, if the total RAM size is not a
+// multiple of 8K then BRAM space is wasted
+
+module ram_wb_harvard #(parameter AWIDTH=13)
+ (input wb_clk_i,
+ input wb_rst_i,
+
+ input [AWIDTH-1:0] iwb_adr_i,
+ input [31:0] iwb_dat_i,
+ output reg [31:0] iwb_dat_o,
+ input iwb_we_i,
+ output reg iwb_ack_o,
+ input iwb_stb_i,
+ input [3:0] iwb_sel_i,
+
+ input [AWIDTH-1:0] dwb_adr_i,
+ input [31:0] dwb_dat_i,
+ output reg [31:0] dwb_dat_o,
+ input dwb_we_i,
+ output reg dwb_ack_o,
+ input dwb_stb_i,
+ input [3:0] dwb_sel_i);
+
+ reg [7:0] ram0 [0:(1<<(AWIDTH-2))-1];
+ reg [7:0] ram1 [0:(1<<(AWIDTH-2))-1];
+ reg [7:0] ram2 [0:(1<<(AWIDTH-2))-1];
+ reg [7:0] ram3 [0:(1<<(AWIDTH-2))-1];
+
+ // Instruction Read Port
+ always @(posedge wb_clk_i)
+ iwb_ack_o <= iwb_stb_i & ~iwb_ack_o;
+
+ always @(posedge wb_clk_i)
+ iwb_dat_o[31:24] <= ram3[iwb_adr_i[AWIDTH-1:2]];
+ always @(posedge wb_clk_i)
+ iwb_dat_o[23:16] <= ram2[iwb_adr_i[AWIDTH-1:2]];
+ always @(posedge wb_clk_i)
+ iwb_dat_o[15:8] <= ram1[iwb_adr_i[AWIDTH-1:2]];
+ always @(posedge wb_clk_i)
+ iwb_dat_o[7:0] <= ram0[iwb_adr_i[AWIDTH-1:2]];
+
+ always @(posedge wb_clk_i)
+ if(iwb_we_i & iwb_stb_i & iwb_sel_i[3])
+ ram3[iwb_adr_i[AWIDTH-1:2]] <= iwb_dat_i[31:24];
+ always @(posedge wb_clk_i)
+ if(iwb_we_i & iwb_stb_i & iwb_sel_i[2])
+ ram2[iwb_adr_i[AWIDTH-1:2]] <= iwb_dat_i[23:16];
+ always @(posedge wb_clk_i)
+ if(iwb_we_i & iwb_stb_i & iwb_sel_i[1])
+ ram1[iwb_adr_i[AWIDTH-1:2]] <= iwb_dat_i[15:8];
+ always @(posedge wb_clk_i)
+ if(iwb_we_i & iwb_stb_i & iwb_sel_i[0])
+ ram0[iwb_adr_i[AWIDTH-1:2]] <= iwb_dat_i[7:0];
+
+ // Data Port
+ always @(posedge wb_clk_i)
+ dwb_ack_o <= dwb_stb_i & ~dwb_ack_o;
+
+ always @(posedge wb_clk_i)
+ dwb_dat_o[31:24] <= ram3[dwb_adr_i[AWIDTH-1:2]];
+ always @(posedge wb_clk_i)
+ dwb_dat_o[23:16] <= ram2[dwb_adr_i[AWIDTH-1:2]];
+ always @(posedge wb_clk_i)
+ dwb_dat_o[15:8] <= ram1[dwb_adr_i[AWIDTH-1:2]];
+ always @(posedge wb_clk_i)
+ dwb_dat_o[7:0] <= ram0[dwb_adr_i[AWIDTH-1:2]];
+
+ always @(posedge wb_clk_i)
+ if(dwb_we_i & dwb_stb_i & dwb_sel_i[3])
+ ram3[dwb_adr_i[AWIDTH-1:2]] <= dwb_dat_i[31:24];
+ always @(posedge wb_clk_i)
+ if(dwb_we_i & dwb_stb_i & dwb_sel_i[2])
+ ram2[dwb_adr_i[AWIDTH-1:2]] <= dwb_dat_i[23:16];
+ always @(posedge wb_clk_i)
+ if(dwb_we_i & dwb_stb_i & dwb_sel_i[1])
+ ram1[dwb_adr_i[AWIDTH-1:2]] <= dwb_dat_i[15:8];
+ always @(posedge wb_clk_i)
+ if(dwb_we_i & dwb_stb_i & dwb_sel_i[0])
+ ram0[dwb_adr_i[AWIDTH-1:2]] <= dwb_dat_i[7:0];
+
+endmodule // ram_wb_harvard
+
diff --git a/fpga/usrp2/control_lib/reset_sync.v b/fpga/usrp2/control_lib/reset_sync.v
new file mode 100644
index 000000000..94d966840
--- /dev/null
+++ b/fpga/usrp2/control_lib/reset_sync.v
@@ -0,0 +1,16 @@
+
+
+module reset_sync
+ (input clk,
+ input reset_in,
+ output reg reset_out);
+
+ reg reset_int;
+
+ always @(posedge clk or posedge reset_in)
+ if(reset_in)
+ {reset_out,reset_int} <= 2'b11;
+ else
+ {reset_out,reset_int} <= {reset_int,1'b0};
+
+endmodule // reset_sync
diff --git a/fpga/usrp2/control_lib/sd_spi.v b/fpga/usrp2/control_lib/sd_spi.v
new file mode 100644
index 000000000..3f4d7f46a
--- /dev/null
+++ b/fpga/usrp2/control_lib/sd_spi.v
@@ -0,0 +1,70 @@
+module sd_spi
+ (input clk,
+ input rst,
+
+ // SD Card interface
+ output reg sd_clk,
+ output sd_mosi,
+ input sd_miso,
+
+ // Controls
+ input [7:0] clk_div,
+ input [7:0] send_dat,
+ output [7:0] rcv_dat,
+ input go,
+ output ready);
+
+ reg [7:0] clk_ctr;
+ reg [3:0] bit_ctr;
+
+ wire bit_ready = (clk_ctr == 8'd0);
+ wire bit_busy = (clk_ctr != 8'd0);
+ wire bit_done = (clk_ctr == clk_div);
+
+ wire send_clk_hi = (clk_ctr == (clk_div>>1));
+ wire latch_dat = (clk_ctr == (clk_div - 8'd2));
+ wire send_clk_lo = (clk_ctr == (clk_div - 8'd1));
+
+ wire send_bit = (bit_ready && (bit_ctr != 0));
+ assign ready = (bit_ctr == 0);
+
+ always @(posedge clk)
+ if(rst)
+ clk_ctr <= 0;
+ else if(bit_done)
+ clk_ctr <= 0;
+ else if(bit_busy)
+ clk_ctr <= clk_ctr + 1;
+ else if(send_bit)
+ clk_ctr <= 1;
+
+ always @(posedge clk)
+ if(rst)
+ sd_clk <= 0;
+ else if(send_clk_hi)
+ sd_clk <= 1;
+ else if(send_clk_lo)
+ sd_clk <= 0;
+
+ always @(posedge clk)
+ if(rst)
+ bit_ctr <= 0;
+ else if(bit_done)
+ if(bit_ctr == 4'd8)
+ bit_ctr <= 0;
+ else
+ bit_ctr <= bit_ctr + 1;
+ else if(bit_ready & go)
+ bit_ctr <= 1;
+
+ reg [7:0] shift_reg;
+ always @(posedge clk)
+ if(go)
+ shift_reg <= send_dat;
+ else if(latch_dat)
+ shift_reg <= {shift_reg[6:0],sd_miso};
+
+ assign sd_mosi = shift_reg[7];
+ assign rcv_dat = shift_reg;
+
+endmodule // sd_spi
diff --git a/fpga/usrp2/control_lib/sd_spi_tb.v b/fpga/usrp2/control_lib/sd_spi_tb.v
new file mode 100644
index 000000000..e30a5bdf6
--- /dev/null
+++ b/fpga/usrp2/control_lib/sd_spi_tb.v
@@ -0,0 +1,40 @@
+
+
+module sd_spi_tb;
+
+ reg clk = 0;
+ always #5 clk = ~clk;
+ reg rst = 1;
+ initial #32 rst = 0;
+
+ wire sd_clk, sd_mosi, sd_miso;
+ wire [7:0] clk_div = 12;
+ wire [7:0] send_dat = 23;
+ wire [7:0] rcv_dat;
+
+ wire ready;
+ reg go = 0;
+ initial
+ begin
+ repeat (100)
+ @(posedge clk);
+ go <= 1;
+ @(posedge clk);
+ go <= 0;
+ end
+
+ sd_spi dut(.clk(clk),.rst(rst),
+ .sd_clk(sd_clk),.sd_mosi(sd_mosi),.sd_miso(sd_miso),
+ .clk_div(clk_div),.send_dat(send_dat),.rcv_dat(rcv_dat),
+ .go(go),.ready(ready) );
+
+ initial
+ begin
+ $dumpfile("sd_spi_tb.vcd");
+ $dumpvars(0,sd_spi_tb);
+ end
+
+ initial
+ #10000 $finish();
+
+endmodule // sd_spi_tb
diff --git a/fpga/usrp2/control_lib/sd_spi_wb.v b/fpga/usrp2/control_lib/sd_spi_wb.v
new file mode 100644
index 000000000..7a6258b56
--- /dev/null
+++ b/fpga/usrp2/control_lib/sd_spi_wb.v
@@ -0,0 +1,76 @@
+
+// Wishbone module for spi communications with an SD Card
+// The programming interface is simple --
+// Write the desired clock divider to address 1 (should be 1 or higher)
+// Status is in address 0. A 1 indicates the last transaction is done and it is safe to
+// send another
+// Writing a byte to address 2 sends that byte over SPI. When it is done,
+// status (addr 0) goes high again, and the received byte can be read from address 3.
+
+module sd_spi_wb
+ (input clk,
+ input rst,
+
+ // SD Card interface
+ output sd_clk,
+ output sd_csn,
+ output sd_mosi,
+ input sd_miso,
+
+ input wb_cyc_i,
+ input wb_stb_i,
+ input wb_we_i,
+ input [1:0] wb_adr_i,
+ input [7:0] wb_dat_i,
+ output reg [7:0] wb_dat_o,
+ output reg wb_ack_o);
+
+ localparam ADDR_STATUS = 0;
+ localparam ADDR_CLKDIV = 1;
+ localparam ADDR_WRITE = 2;
+ localparam ADDR_READ = 3;
+
+ wire [7:0] status, rcv_dat;
+ reg [7:0] clkdiv;
+ wire ready;
+ reg ack_d1;
+
+ reg cs_reg;
+ assign sd_csn = ~cs_reg; // FIXME
+
+ always @(posedge clk)
+ if(rst) ack_d1 <= 0;
+ else ack_d1 <= wb_ack_o;
+
+ always @(posedge clk)
+ if(rst) wb_ack_o <= 0;
+ else wb_ack_o <= wb_cyc_i & wb_stb_i & ~ack_d1;
+
+ always @(posedge clk)
+ case(wb_adr_i)
+ ADDR_STATUS : wb_dat_o <= {7'd0,ready};
+ ADDR_CLKDIV : wb_dat_o <= clkdiv;
+ ADDR_READ : wb_dat_o <= rcv_dat;
+ default : wb_dat_o <= 0;
+ endcase // case(wb_adr_i)
+
+ always @(posedge clk)
+ if(rst)
+ begin
+ clkdiv <= 200;
+ cs_reg <= 0;
+ end
+ else if(wb_we_i & wb_stb_i & wb_cyc_i & wb_ack_o)
+ case(wb_adr_i)
+ ADDR_STATUS : cs_reg <= wb_dat_i;
+ ADDR_CLKDIV : clkdiv <= wb_dat_i;
+ endcase // case(wb_adr_i)
+
+ wire go = wb_we_i & wb_stb_i & wb_cyc_i & wb_ack_o & (wb_adr_i == ADDR_WRITE);
+
+ sd_spi sd_spi(.clk(clk),.rst(rst),
+ .sd_clk(sd_clk),.sd_mosi(sd_mosi),.sd_miso(sd_miso),
+ .clk_div(clkdiv),.send_dat(wb_dat_i),.rcv_dat(rcv_dat),
+ .go(go),.ready(ready) );
+
+endmodule // sd_spi_wb
diff --git a/fpga/usrp2/control_lib/setting_reg.v b/fpga/usrp2/control_lib/setting_reg.v
new file mode 100644
index 000000000..c8aff230f
--- /dev/null
+++ b/fpga/usrp2/control_lib/setting_reg.v
@@ -0,0 +1,23 @@
+
+
+module setting_reg
+ #(parameter my_addr = 0, parameter at_reset=32'd0)
+ (input clk, input rst, input strobe, input wire [7:0] addr,
+ input wire [31:0] in, output reg [31:0] out, output reg changed);
+
+ always @(posedge clk)
+ if(rst)
+ begin
+ out <= at_reset;
+ changed <= 1'b0;
+ end
+ else
+ if(strobe & (my_addr==addr))
+ begin
+ out <= in;
+ changed <= 1'b1;
+ end
+ else
+ changed <= 1'b0;
+
+endmodule // setting_reg
diff --git a/fpga/usrp2/control_lib/settings_bus.v b/fpga/usrp2/control_lib/settings_bus.v
new file mode 100644
index 000000000..d01a30ab4
--- /dev/null
+++ b/fpga/usrp2/control_lib/settings_bus.v
@@ -0,0 +1,49 @@
+
+// Grab settings off the wishbone bus, send them out to our simpler bus on the fast clock
+
+module settings_bus
+ #(parameter AWIDTH=16, parameter DWIDTH=32)
+ (input wb_clk,
+ input wb_rst,
+ input [AWIDTH-1:0] wb_adr_i,
+ input [DWIDTH-1:0] wb_dat_i,
+ input wb_stb_i,
+ input wb_we_i,
+ output reg wb_ack_o,
+ input sys_clk,
+ output strobe,
+ output reg [7:0] addr,
+ output reg [31:0] data);
+
+ reg stb_int, stb_int_d1;
+
+ always @(posedge wb_clk)
+ if(wb_rst)
+ begin
+ stb_int <= 1'b0;
+ addr <= 8'd0;
+ data <= 32'd0;
+ end
+ else if(wb_we_i & wb_stb_i)
+ begin
+ stb_int <= 1'b1;
+ addr <= wb_adr_i[9:2];
+ data <= wb_dat_i;
+ end
+ else
+ stb_int <= 1'b0;
+
+ always @(posedge wb_clk)
+ if(wb_rst)
+ wb_ack_o <= 0;
+ else
+ wb_ack_o <= wb_stb_i & ~wb_ack_o;
+
+ always @(posedge wb_clk)
+ stb_int_d1 <= stb_int;
+
+ //assign strobe = stb_int & ~stb_int_d1;
+ assign strobe = stb_int & wb_ack_o;
+
+endmodule // settings_bus
+
diff --git a/fpga/usrp2/control_lib/shortfifo.v b/fpga/usrp2/control_lib/shortfifo.v
new file mode 100644
index 000000000..d8ce1428e
--- /dev/null
+++ b/fpga/usrp2/control_lib/shortfifo.v
@@ -0,0 +1,87 @@
+
+module shortfifo
+ #(parameter WIDTH=32)
+ (input clk, input rst,
+ input [WIDTH-1:0] datain,
+ output [WIDTH-1:0] dataout,
+ input read,
+ input write,
+ input clear,
+ output reg full,
+ output reg empty,
+ output reg [4:0] space,
+ output reg [4:0] occupied);
+
+ reg [3:0] a;
+ genvar i;
+
+ generate
+ for (i=0;i<WIDTH;i=i+1)
+ begin : gen_srl16
+ SRL16E
+ srl16e(.Q(dataout[i]),
+ .A0(a[0]),.A1(a[1]),.A2(a[2]),.A3(a[3]),
+ .CE(write),.CLK(clk),.D(datain[i]));
+ end
+ endgenerate
+
+ always @(posedge clk)
+ if(rst)
+ begin
+ a <= 0;
+ empty <= 1;
+ full <= 0;
+ end
+ else if(clear)
+ begin
+ a <= 0;
+ empty <= 1;
+ full<= 0;
+ end
+ else if(read & ~write)
+ begin
+ full <= 0;
+ if(a==0)
+ empty <= 1;
+ else
+ a <= a - 1;
+ end
+ else if(write & ~read)
+ begin
+ empty <= 0;
+ if(~empty)
+ a <= a + 1;
+ if(a == 14)
+ full <= 1;
+ end
+
+ // NOTE will fail if you write into a full fifo or read from an empty one
+
+ //////////////////////////////////////////////////////////////
+ // space and occupied are used for diagnostics, not
+ // guaranteed correct
+
+ //assign space = full ? 0 : empty ? 16 : 15-a;
+ //assign occupied = empty ? 0 : full ? 16 : a+1;
+
+ always @(posedge clk)
+ if(rst)
+ space <= 16;
+ else if(clear)
+ space <= 16;
+ else if(read & ~write)
+ space <= space + 1;
+ else if(write & ~read)
+ space <= space - 1;
+
+ always @(posedge clk)
+ if(rst)
+ occupied <= 0;
+ else if(clear)
+ occupied <= 0;
+ else if(read & ~write)
+ occupied <= occupied - 1;
+ else if(write & ~read)
+ occupied <= occupied + 1;
+
+endmodule // shortfifo
diff --git a/fpga/usrp2/control_lib/simple_uart.v b/fpga/usrp2/control_lib/simple_uart.v
new file mode 100644
index 000000000..22f0e70a2
--- /dev/null
+++ b/fpga/usrp2/control_lib/simple_uart.v
@@ -0,0 +1,61 @@
+
+module simple_uart
+ #(parameter TXDEPTH = 1,
+ parameter RXDEPTH = 1)
+ (input clk_i, input rst_i,
+ input we_i, input stb_i, input cyc_i, output reg ack_o,
+ input [2:0] adr_i, input [31:0] dat_i, output reg [31:0] dat_o,
+ output rx_int_o, output tx_int_o, output tx_o, input rx_i, output baud_o);
+
+ // Register Map
+ localparam SUART_CLKDIV = 0;
+ localparam SUART_TXLEVEL = 1;
+ localparam SUART_RXLEVEL = 2;
+ localparam SUART_TXCHAR = 3;
+ localparam SUART_RXCHAR = 4;
+
+ wire wb_acc = cyc_i & stb_i; // WISHBONE access
+ wire wb_wr = wb_acc & we_i; // WISHBONE write access
+
+ reg [15:0] clkdiv;
+ wire [7:0] rx_char;
+ wire tx_fifo_full, rx_fifo_empty;
+ wire [7:0] tx_fifo_level, rx_fifo_level;
+
+ always @(posedge clk_i)
+ if (rst_i)
+ ack_o <= 1'b0;
+ else
+ ack_o <= wb_acc & ~ack_o;
+
+ always @(posedge clk_i)
+ if (rst_i)
+ clkdiv <= 0;
+ else if (wb_wr)
+ case(adr_i)
+ SUART_CLKDIV : clkdiv <= dat_i[15:0];
+ endcase // case(adr_i)
+
+ always @(posedge clk_i)
+ case (adr_i)
+ SUART_TXLEVEL : dat_o <= tx_fifo_level;
+ SUART_RXLEVEL : dat_o <= rx_fifo_level;
+ SUART_RXCHAR : dat_o <= rx_char;
+ endcase // case(adr_i)
+
+ simple_uart_tx #(.DEPTH(TXDEPTH)) simple_uart_tx
+ (.clk(clk_i),.rst(rst_i),
+ .fifo_in(dat_i[7:0]),.fifo_write(ack_o && wb_wr && (adr_i == SUART_TXCHAR)),
+ .fifo_level(tx_fifo_level),.fifo_full(tx_fifo_full),
+ .clkdiv(clkdiv),.baudclk(baud_o),.tx(tx_o));
+
+ simple_uart_rx #(.DEPTH(RXDEPTH)) simple_uart_rx
+ (.clk(clk_i),.rst(rst_i),
+ .fifo_out(rx_char),.fifo_read(ack_o && ~wb_wr && (adr_i == SUART_RXCHAR)),
+ .fifo_level(rx_fifo_level),.fifo_empty(rx_fifo_empty),
+ .clkdiv(clkdiv),.rx(rx_i));
+
+ assign tx_int_o = ~tx_fifo_full;
+ assign rx_int_o = ~rx_fifo_empty;
+
+endmodule // simple_uart
diff --git a/fpga/usrp2/control_lib/simple_uart_rx.v b/fpga/usrp2/control_lib/simple_uart_rx.v
new file mode 100644
index 000000000..debdd618b
--- /dev/null
+++ b/fpga/usrp2/control_lib/simple_uart_rx.v
@@ -0,0 +1,64 @@
+
+
+module simple_uart_rx
+ #(parameter DEPTH=0)
+ (input clk, input rst,
+ output [7:0] fifo_out, input fifo_read, output [7:0] fifo_level, output fifo_empty,
+ input [15:0] clkdiv, input rx);
+
+ reg rx_d1, rx_d2;
+ always @(posedge clk)
+ if(rst)
+ {rx_d2,rx_d1} <= 0;
+ else
+ {rx_d2,rx_d1} <= {rx_d1,rx};
+
+ reg [15:0] baud_ctr;
+ reg [3:0] bit_ctr;
+ reg [7:0] sr;
+
+ wire neg_trans = rx_d2 & ~rx_d1;
+ wire shift_now = baud_ctr == (clkdiv>>1);
+ wire stop_now = (bit_ctr == 10) && shift_now;
+ wire go_now = (bit_ctr == 0) && neg_trans;
+
+ always @(posedge clk)
+ if(rst)
+ sr <= 0;
+ else if(shift_now)
+ sr <= {rx_d2,sr[7:1]};
+
+ always @(posedge clk)
+ if(rst)
+ baud_ctr <= 0;
+ else
+ if(go_now)
+ baud_ctr <= 1;
+ else if(stop_now)
+ baud_ctr <= 0;
+ else if(baud_ctr >= clkdiv)
+ baud_ctr <= 1;
+ else if(baud_ctr != 0)
+ baud_ctr <= baud_ctr + 1;
+
+ always @(posedge clk)
+ if(rst)
+ bit_ctr <= 0;
+ else
+ if(go_now)
+ bit_ctr <= 1;
+ else if(stop_now)
+ bit_ctr <= 0;
+ else if(baud_ctr == clkdiv)
+ bit_ctr <= bit_ctr + 1;
+
+ wire full;
+ wire write = ~full & rx_d2 & stop_now;
+
+ medfifo #(.WIDTH(8),.DEPTH(DEPTH)) fifo
+ (.clk(clk),.rst(rst),
+ .datain(sr),.write(write),.full(full),
+ .dataout(fifo_out),.read(fifo_read),.empty(fifo_empty),
+ .clear(0),.space(),.occupied(fifo_level) );
+
+endmodule // simple_uart_rx
diff --git a/fpga/usrp2/control_lib/simple_uart_tx.v b/fpga/usrp2/control_lib/simple_uart_tx.v
new file mode 100644
index 000000000..e11a347ed
--- /dev/null
+++ b/fpga/usrp2/control_lib/simple_uart_tx.v
@@ -0,0 +1,60 @@
+
+module simple_uart_tx
+ #(parameter DEPTH=0)
+ (input clk, input rst,
+ input [7:0] fifo_in, input fifo_write, output [7:0] fifo_level, output fifo_full,
+ input [15:0] clkdiv, output baudclk, output reg tx);
+
+ reg [15:0] baud_ctr;
+ reg [3:0] bit_ctr;
+
+ wire read, empty;
+ wire [7:0] char_to_send;
+
+ medfifo #(.WIDTH(8),.DEPTH(DEPTH)) fifo
+ (.clk(clk),.rst(rst),
+ .datain(fifo_in),.write(fifo_write),.full(fifo_full),
+ .dataout(char_to_send),.read(read),.empty(empty),
+ .clear(0),.space(fifo_level),.occupied() );
+
+ always @(posedge clk)
+ if(rst)
+ baud_ctr <= 0;
+ else if (baud_ctr >= clkdiv)
+ baud_ctr <= 0;
+ else
+ baud_ctr <= baud_ctr + 1;
+
+ always @(posedge clk)
+ if(rst)
+ bit_ctr <= 0;
+ else if(baud_ctr == clkdiv)
+ if(bit_ctr == 9)
+ bit_ctr <= 0;
+ else if(bit_ctr != 0)
+ bit_ctr <= bit_ctr + 1;
+ else if(~empty)
+ bit_ctr <= 1;
+
+ always @(posedge clk)
+ if(rst)
+ tx <= 1;
+ else
+ case(bit_ctr)
+ 0 : tx <= 1;
+ 1 : tx <= 0;
+ 2 : tx <= char_to_send[0];
+ 3 : tx <= char_to_send[1];
+ 4 : tx <= char_to_send[2];
+ 5 : tx <= char_to_send[3];
+ 6 : tx <= char_to_send[4];
+ 7 : tx <= char_to_send[5];
+ 8 : tx <= char_to_send[6];
+ 9 : tx <= char_to_send[7];
+ default : tx <= 1;
+ endcase // case(bit_ctr)
+
+ assign read = (bit_ctr == 9) && (baud_ctr == clkdiv);
+ assign baudclk = (baud_ctr == 1); // Only for debug purposes
+
+endmodule // simple_uart_tx
diff --git a/fpga/usrp2/control_lib/spi.v b/fpga/usrp2/control_lib/spi.v
new file mode 100644
index 000000000..a80c488e9
--- /dev/null
+++ b/fpga/usrp2/control_lib/spi.v
@@ -0,0 +1,84 @@
+
+
+// AD9510 Register Map (from datasheet Rev. A)
+
+/* INSTRUCTION word format (16 bits)
+ * 15 Read = 1, Write = 0
+ * 14:13 W1/W0, Number of bytes 00 - 1, 01 - 2, 10 - 3, 11 - stream
+ * 12:0 Address
+ */
+
+/* ADDR Contents Value (hex)
+ * 00 Serial Config Port 10 (def) -- MSB first, SDI/SDO separate
+ * 04 A Counter
+ * 05-06 B Counter
+ * 07-0A PLL Control
+ * 0B-0C R Divider
+ * 0D PLL Control
+ * 34-3A Fine Delay
+ * 3C-3F LVPECL Outs
+ * 40-43 LVDS/CMOS Outs
+ * 45 Clock select, power down
+ * 48-57 Dividers
+ * 58 Func and Sync
+ * 5A Update regs
+ */
+
+
+module spi
+ (input reset,
+ input clk,
+
+ // SPI signals
+ output sen,
+ output sclk,
+ input sdi,
+ output sdo,
+
+ // Interfaces
+ input read_1,
+ input write_1,
+ input [15:0] command_1,
+ input [15:0] wdata_1,
+ output [15:0] rdata_1,
+ output reg done_1,
+ input msb_first_1,
+ input [5:0] command_width_1,
+ input [5:0] data_width_1,
+ input [7:0] clkdiv_1
+
+ );
+
+ reg [15:0] command, wdata, rdata;
+ reg done;
+
+ always @(posedge clk)
+ if(reset)
+ done_1 <= #1 1'b0;
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ counter <= #1 7'd0;
+ command <= #1 20'd0;
+ end
+ else if(start)
+ begin
+ counter <= #1 7'd1;
+ command <= #1 {read,w,addr_data};
+ end
+ else if( |counter && ~done )
+ begin
+ counter <= #1 counter + 7'd1;
+ if(~counter[0])
+ command <= {command[22:0],1'b0};
+ end
+
+ wire done = (counter == 8'd49);
+
+ assign sen = (done | counter == 8'd0); // CSB is high when we're not doing anything
+ assign sclk = ~counter[0];
+ assign sdo = command[23];
+
+
+endmodule // clock_control
diff --git a/fpga/usrp2/control_lib/srl.v b/fpga/usrp2/control_lib/srl.v
new file mode 100644
index 000000000..fa28c7669
--- /dev/null
+++ b/fpga/usrp2/control_lib/srl.v
@@ -0,0 +1,21 @@
+
+module srl
+ #(parameter WIDTH=18)
+ (input clk,
+ input write,
+ input [WIDTH-1:0] in,
+ input [3:0] addr,
+ output [WIDTH-1:0] out);
+
+ genvar i;
+ generate
+ for (i=0;i<WIDTH;i=i+1)
+ begin : gen_srl
+ SRL16E
+ srl16e(.Q(out[i]),
+ .A0(addr[0]),.A1(addr[1]),.A2(addr[2]),.A3(addr[3]),
+ .CE(write),.CLK(clk),.D(in[i]));
+ end
+ endgenerate
+
+endmodule // srl
diff --git a/fpga/usrp2/control_lib/ss_rcvr.v b/fpga/usrp2/control_lib/ss_rcvr.v
new file mode 100644
index 000000000..8e650d21b
--- /dev/null
+++ b/fpga/usrp2/control_lib/ss_rcvr.v
@@ -0,0 +1,81 @@
+
+
+// Source-synchronous receiver
+// Assumes both clocks are at the same rate
+// Relative clock phase is
+// unknown
+// variable
+// bounded
+// The output will come several cycles later than the input
+
+// This should synthesize efficiently in Xilinx distributed ram cells,
+// which is why we use a buffer depth of 16
+
+// FIXME Async reset on rxclk side?
+
+module ss_rcvr
+ #(parameter WIDTH=16)
+ (input rxclk,
+ input sysclk,
+ input rst,
+
+ input [WIDTH-1:0] data_in,
+ output [WIDTH-1:0] data_out,
+ output reg clock_present);
+
+ wire [3:0] rd_addr, wr_addr;
+
+ // Distributed RAM
+ reg [WIDTH-1:0] buffer [0:15];
+ always @(posedge rxclk)
+ buffer[wr_addr] <= data_in;
+
+ assign data_out = buffer[rd_addr];
+
+ // Write address generation
+ reg [3:0] wr_counter;
+ always @(posedge rxclk or posedge rst)
+ if (rst)
+ wr_counter <= 0;
+ else
+ wr_counter <= wr_counter + 1;
+
+ assign wr_addr = {wr_counter[3], ^wr_counter[3:2], ^wr_counter[2:1], ^wr_counter[1:0]};
+
+ // Read Address generation
+ wire [3:0] wr_ctr_sys, diff, abs_diff;
+ reg [3:0] wr_addr_sys_d1, wr_addr_sys_d2;
+ reg [3:0] rd_counter;
+
+ assign rd_addr = {rd_counter[3], ^rd_counter[3:2], ^rd_counter[2:1], ^rd_counter[1:0]};
+
+ always @(posedge sysclk)
+ wr_addr_sys_d1 <= wr_addr;
+
+ always @(posedge sysclk)
+ wr_addr_sys_d2 <= wr_addr_sys_d1;
+
+ assign wr_ctr_sys = {wr_addr_sys_d2[3],^wr_addr_sys_d2[3:2],^wr_addr_sys_d2[3:1],^wr_addr_sys_d2[3:0]};
+
+ assign diff = wr_ctr_sys - rd_counter;
+ assign abs_diff = diff[3] ? (~diff+1) : diff;
+
+ always @(posedge sysclk)
+ if(rst)
+ begin
+ clock_present <= 0;
+ rd_counter <= 0;
+ end
+ else
+ if(~clock_present)
+ if(abs_diff > 5)
+ clock_present <= 1;
+ else
+ ;
+ else
+ if(abs_diff<3)
+ clock_present <= 0;
+ else
+ rd_counter <= rd_counter + 1;
+
+endmodule // ss_rcvr
diff --git a/fpga/usrp2/control_lib/system_control.v b/fpga/usrp2/control_lib/system_control.v
new file mode 100644
index 000000000..5d89f13db
--- /dev/null
+++ b/fpga/usrp2/control_lib/system_control.v
@@ -0,0 +1,47 @@
+// System bootup order:
+// 0 - Internal POR to reset this block. Maybe control it from CPLD in the future?
+// 1 - Everything in reset
+// 2 - Take RAM Loader out of reset
+// 3 - When RAM Loader done, take processor and wishbone out of reset
+
+module system_control
+ (input wb_clk_i,
+ output reg ram_loader_rst_o,
+ output reg wb_rst_o,
+ input ram_loader_done_i
+ );
+
+ reg POR = 1'b1;
+ reg [3:0] POR_ctr;
+
+ initial POR_ctr = 4'd0;
+ always @(posedge wb_clk_i)
+ if(POR_ctr == 4'd15)
+ POR <= 1'b0;
+ else
+ POR_ctr <= POR_ctr + 4'd1;
+
+ always @(posedge POR or posedge wb_clk_i)
+ if(POR)
+ ram_loader_rst_o <= 1'b1;
+ else
+ ram_loader_rst_o <= #1 1'b0;
+
+ // Main system reset
+ reg delayed_rst;
+
+ always @(posedge POR or posedge wb_clk_i)
+ if(POR)
+ begin
+ wb_rst_o <= 1'b1;
+ delayed_rst <= 1'b1;
+ end
+ else if(ram_loader_done_i)
+ begin
+ delayed_rst <= 1'b0;
+ wb_rst_o <= delayed_rst;
+ end
+
+endmodule // system_control
+
+
diff --git a/fpga/usrp2/control_lib/system_control_tb.v b/fpga/usrp2/control_lib/system_control_tb.v
new file mode 100644
index 000000000..a8eff4811
--- /dev/null
+++ b/fpga/usrp2/control_lib/system_control_tb.v
@@ -0,0 +1,57 @@
+
+
+module system_control_tb();
+
+ reg aux_clk, clk_fpga;
+ wire wb_clk, dsp_clk;
+ wire wb_rst, dsp_rst, rl_rst, proc_rst;
+
+ reg rl_done, clock_ready;
+
+ initial aux_clk = 1'b0;
+ always #25 aux_clk = ~aux_clk;
+
+ initial clk_fpga = 1'b0;
+
+ initial clock_ready = 1'b0;
+ initial
+ begin
+ @(negedge proc_rst);
+ #1003 clock_ready <= 1'b1;
+ end
+
+ always #7 clk_fpga = ~clk_fpga;
+
+ initial begin
+ $dumpfile("system_control_tb.vcd");
+ $dumpvars(0,system_control_tb);
+ end
+
+ initial #10000 $finish;
+
+ initial
+ begin
+ @(negedge rl_rst);
+ rl_done <= 1'b0;
+ #1325 rl_done <= 1'b1;
+ end
+
+ initial
+ begin
+ @(negedge proc_rst);
+ clock_ready <= 1'b0;
+ #327 clock_ready <= 1'b1;
+ end
+
+ system_control
+ system_control(.aux_clk_i(aux_clk),.clk_fpga_i(clk_fpga),
+ .dsp_clk_o(dsp_clk),.wb_clk_o(wb_clk),
+ .ram_loader_rst_o(rl_rst),
+ .processor_rst_o(proc_rst),
+ .wb_rst_o(wb_rst),
+ .dsp_rst_o(dsp_rst),
+ .ram_loader_done_i(rl_done),
+ .clock_ready_i(clock_ready),
+ .debug_o());
+
+endmodule // system_control_tb
diff --git a/fpga/usrp2/control_lib/traffic_cop.v b/fpga/usrp2/control_lib/traffic_cop.v
new file mode 100644
index 000000000..e7579656a
--- /dev/null
+++ b/fpga/usrp2/control_lib/traffic_cop.v
@@ -0,0 +1,25 @@
+
+module traffic_cop();
+
+
+endmodule // traffic_cop
+
+
+
+/*
+
+ Traffic Cop to control buffer pool
+
+ Inputs
+
+ Commands
+
+ Basic Operations
+
+ Outputs
+
+
+
+
+
+ */
diff --git a/fpga/usrp2/control_lib/wb_1master.v b/fpga/usrp2/control_lib/wb_1master.v
new file mode 100644
index 000000000..fb313efae
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_1master.v
@@ -0,0 +1,464 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE Connection Bus Top Level ////
+//// ////
+//// ////
+//// Original Author: Johny Chi ////
+//// chisuhua@yahoo.com.cn ////
+//// Modified By Matt Ettus, matt@ettus.com ////
+//// ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2007 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// Up to 8 slaves share a Wishbone Bus connection to 1 master
+
+ module wb_1master
+ #(parameter decode_w = 8, // address decode width
+ parameter s0_addr = 8'h0, // slave 0 address
+ parameter s0_mask = 8'h0, // slave 0 don't cares
+ parameter s1_addr = 8'h0, // slave 1 address
+ parameter s1_mask = 8'h0, // slave 1 don't cares
+ parameter s2_addr = 8'h0, // slave 2 address
+ parameter s2_mask = 8'h0, // slave 2 don't cares
+ parameter s3_addr = 8'h0, // slave 3 address
+ parameter s3_mask = 8'h0, // slave 3 don't cares
+ parameter s4_addr = 8'h0, // slave 4 address
+ parameter s4_mask = 8'h0, // slave 4 don't cares
+ parameter s5_addr = 8'h0, // slave 5 address
+ parameter s5_mask = 8'h0, // slave 5 don't cares
+ parameter s6_addr = 8'h0, // slave 6 address
+ parameter s6_mask = 8'h0, // slave 6 don't cares
+ parameter s7_addr = 8'h0, // slave 7 address
+ parameter s7_mask = 8'h0, // slave 7 don't cares
+ parameter s8_addr = 8'h0, // slave 8 address
+ parameter s8_mask = 8'h0, // slave 8 don't cares
+ parameter s9_addr = 8'h0, // slave 9 address
+ parameter s9_mask = 8'h0, // slave 9 don't cares
+ parameter sa_addr = 8'h0, // slave a address
+ parameter sa_mask = 8'h0, // slave a don't cares
+ parameter sb_addr = 8'h0, // slave b address
+ parameter sb_mask = 8'h0, // slave b don't cares
+ parameter sc_addr = 8'h0, // slave c address
+ parameter sc_mask = 8'h0, // slave c don't cares
+ parameter sd_addr = 8'h0, // slave d address
+ parameter sd_mask = 8'h0, // slave d don't cares
+ parameter se_addr = 8'h0, // slave e address
+ parameter se_mask = 8'h0, // slave e don't cares
+ parameter sf_addr = 8'h0, // slave f address
+ parameter sf_mask = 8'h0, // slave f don't cares
+
+ parameter dw = 32, // Data bus Width
+ parameter aw = 32, // Address bus Width
+ parameter sw = 4) // Number of Select Lines
+
+ (input clk_i,
+ input rst_i,
+
+ // Master Interface
+ input [dw-1:0] m0_dat_i,
+ output [dw-1:0] m0_dat_o,
+ input [aw-1:0] m0_adr_i,
+ input [sw-1:0] m0_sel_i,
+ input m0_we_i,
+ input m0_cyc_i,
+ input m0_stb_i,
+ output m0_ack_o,
+ output m0_err_o,
+ output m0_rty_o,
+
+ // Slave Interfaces
+ input [dw-1:0] s0_dat_i,
+ output [dw-1:0] s0_dat_o,
+ output [aw-1:0] s0_adr_o,
+ output [sw-1:0] s0_sel_o,
+ output s0_we_o,
+ output s0_cyc_o,
+ output s0_stb_o,
+ input s0_ack_i,
+ input s0_err_i,
+ input s0_rty_i,
+
+ input [dw-1:0] s1_dat_i,
+ output [dw-1:0] s1_dat_o,
+ output [aw-1:0] s1_adr_o,
+ output [sw-1:0] s1_sel_o,
+ output s1_we_o,
+ output s1_cyc_o,
+ output s1_stb_o,
+ input s1_ack_i,
+ input s1_err_i,
+ input s1_rty_i,
+
+ input [dw-1:0] s2_dat_i,
+ output [dw-1:0] s2_dat_o,
+ output [aw-1:0] s2_adr_o,
+ output [sw-1:0] s2_sel_o,
+ output s2_we_o,
+ output s2_cyc_o,
+ output s2_stb_o,
+ input s2_ack_i,
+ input s2_err_i,
+ input s2_rty_i,
+
+ input [dw-1:0] s3_dat_i,
+ output [dw-1:0] s3_dat_o,
+ output [aw-1:0] s3_adr_o,
+ output [sw-1:0] s3_sel_o,
+ output s3_we_o,
+ output s3_cyc_o,
+ output s3_stb_o,
+ input s3_ack_i,
+ input s3_err_i,
+ input s3_rty_i,
+
+ input [dw-1:0] s4_dat_i,
+ output [dw-1:0] s4_dat_o,
+ output [aw-1:0] s4_adr_o,
+ output [sw-1:0] s4_sel_o,
+ output s4_we_o,
+ output s4_cyc_o,
+ output s4_stb_o,
+ input s4_ack_i,
+ input s4_err_i,
+ input s4_rty_i,
+
+ input [dw-1:0] s5_dat_i,
+ output [dw-1:0] s5_dat_o,
+ output [aw-1:0] s5_adr_o,
+ output [sw-1:0] s5_sel_o,
+ output s5_we_o,
+ output s5_cyc_o,
+ output s5_stb_o,
+ input s5_ack_i,
+ input s5_err_i,
+ input s5_rty_i,
+
+ input [dw-1:0] s6_dat_i,
+ output [dw-1:0] s6_dat_o,
+ output [aw-1:0] s6_adr_o,
+ output [sw-1:0] s6_sel_o,
+ output s6_we_o,
+ output s6_cyc_o,
+ output s6_stb_o,
+ input s6_ack_i,
+ input s6_err_i,
+ input s6_rty_i,
+
+ input [dw-1:0] s7_dat_i,
+ output [dw-1:0] s7_dat_o,
+ output [aw-1:0] s7_adr_o,
+ output [sw-1:0] s7_sel_o,
+ output s7_we_o,
+ output s7_cyc_o,
+ output s7_stb_o,
+ input s7_ack_i,
+ input s7_err_i,
+ input s7_rty_i,
+
+ input [dw-1:0] s8_dat_i,
+ output [dw-1:0] s8_dat_o,
+ output [aw-1:0] s8_adr_o,
+ output [sw-1:0] s8_sel_o,
+ output s8_we_o,
+ output s8_cyc_o,
+ output s8_stb_o,
+ input s8_ack_i,
+ input s8_err_i,
+ input s8_rty_i,
+
+ input [dw-1:0] s9_dat_i,
+ output [dw-1:0] s9_dat_o,
+ output [aw-1:0] s9_adr_o,
+ output [sw-1:0] s9_sel_o,
+ output s9_we_o,
+ output s9_cyc_o,
+ output s9_stb_o,
+ input s9_ack_i,
+ input s9_err_i,
+ input s9_rty_i,
+
+ input [dw-1:0] sa_dat_i,
+ output [dw-1:0] sa_dat_o,
+ output [aw-1:0] sa_adr_o,
+ output [sw-1:0] sa_sel_o,
+ output sa_we_o,
+ output sa_cyc_o,
+ output sa_stb_o,
+ input sa_ack_i,
+ input sa_err_i,
+ input sa_rty_i,
+
+ input [dw-1:0] sb_dat_i,
+ output [dw-1:0] sb_dat_o,
+ output [aw-1:0] sb_adr_o,
+ output [sw-1:0] sb_sel_o,
+ output sb_we_o,
+ output sb_cyc_o,
+ output sb_stb_o,
+ input sb_ack_i,
+ input sb_err_i,
+ input sb_rty_i,
+
+ input [dw-1:0] sc_dat_i,
+ output [dw-1:0] sc_dat_o,
+ output [aw-1:0] sc_adr_o,
+ output [sw-1:0] sc_sel_o,
+ output sc_we_o,
+ output sc_cyc_o,
+ output sc_stb_o,
+ input sc_ack_i,
+ input sc_err_i,
+ input sc_rty_i,
+
+ input [dw-1:0] sd_dat_i,
+ output [dw-1:0] sd_dat_o,
+ output [aw-1:0] sd_adr_o,
+ output [sw-1:0] sd_sel_o,
+ output sd_we_o,
+ output sd_cyc_o,
+ output sd_stb_o,
+ input sd_ack_i,
+ input sd_err_i,
+ input sd_rty_i,
+
+ input [dw-1:0] se_dat_i,
+ output [dw-1:0] se_dat_o,
+ output [aw-1:0] se_adr_o,
+ output [sw-1:0] se_sel_o,
+ output se_we_o,
+ output se_cyc_o,
+ output se_stb_o,
+ input se_ack_i,
+ input se_err_i,
+ input se_rty_i,
+
+ input [dw-1:0] sf_dat_i,
+ output [dw-1:0] sf_dat_o,
+ output [aw-1:0] sf_adr_o,
+ output [sw-1:0] sf_sel_o,
+ output sf_we_o,
+ output sf_cyc_o,
+ output sf_stb_o,
+ input sf_ack_i,
+ input sf_err_i,
+ input sf_rty_i
+ );
+
+ // ////////////////////////////////////////////////////////////////
+ //
+ // Local wires
+ //
+
+ wire [15:0] ssel_dec;
+ reg [dw-1:0] i_dat_s; // internal share bus , slave data to master
+
+ // Master output Interface
+ assign m0_dat_o = i_dat_s;
+
+ always @*
+ case(ssel_dec)
+ 1 : i_dat_s <= s0_dat_i;
+ 2 : i_dat_s <= s1_dat_i;
+ 4 : i_dat_s <= s2_dat_i;
+ 8 : i_dat_s <= s3_dat_i;
+ 16 : i_dat_s <= s4_dat_i;
+ 32 : i_dat_s <= s5_dat_i;
+ 64 : i_dat_s <= s6_dat_i;
+ 128 : i_dat_s <= s7_dat_i;
+ 256 : i_dat_s <= s8_dat_i;
+ 512 : i_dat_s <= s9_dat_i;
+ 1024 : i_dat_s <= sa_dat_i;
+ 2048 : i_dat_s <= sb_dat_i;
+ 4096 : i_dat_s <= sc_dat_i;
+ 8192 : i_dat_s <= sd_dat_i;
+ 16384 : i_dat_s <= se_dat_i;
+ 32768 : i_dat_s <= sf_dat_i;
+ default : i_dat_s <= s0_dat_i;
+ endcase // case(ssel_dec)
+
+ assign {m0_ack_o, m0_err_o, m0_rty_o}
+ = {s0_ack_i | s1_ack_i | s2_ack_i | s3_ack_i | s4_ack_i | s5_ack_i | s6_ack_i | s7_ack_i |
+ s8_ack_i | s9_ack_i | sa_ack_i | sb_ack_i | sc_ack_i | sd_ack_i | se_ack_i | sf_ack_i ,
+ s0_err_i | s1_err_i | s2_err_i | s3_err_i | s4_err_i | s5_err_i | s6_err_i | s7_err_i |
+ s8_err_i | s9_err_i | sa_err_i | sb_err_i | sc_err_i | sd_err_i | se_err_i | sf_err_i ,
+ s0_rty_i | s1_rty_i | s2_rty_i | s3_rty_i | s4_rty_i | s5_rty_i | s6_rty_i | s7_rty_i |
+ s8_rty_i | s9_rty_i | sa_rty_i | sb_rty_i | sc_rty_i | sd_rty_i | se_rty_i | sf_rty_i };
+
+ // Slave output interfaces
+ assign s0_adr_o = m0_adr_i;
+ assign s0_sel_o = m0_sel_i;
+ assign s0_dat_o = m0_dat_i;
+ assign s0_we_o = m0_we_i;
+ assign s0_cyc_o = m0_cyc_i;
+ assign s0_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[0];
+
+ assign s1_adr_o = m0_adr_i;
+ assign s1_sel_o = m0_sel_i;
+ assign s1_dat_o = m0_dat_i;
+ assign s1_we_o = m0_we_i;
+ assign s1_cyc_o = m0_cyc_i;
+ assign s1_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[1];
+
+ assign s2_adr_o = m0_adr_i;
+ assign s2_sel_o = m0_sel_i;
+ assign s2_dat_o = m0_dat_i;
+ assign s2_we_o = m0_we_i;
+ assign s2_cyc_o = m0_cyc_i;
+ assign s2_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[2];
+
+ assign s3_adr_o = m0_adr_i;
+ assign s3_sel_o = m0_sel_i;
+ assign s3_dat_o = m0_dat_i;
+ assign s3_we_o = m0_we_i;
+ assign s3_cyc_o = m0_cyc_i;
+ assign s3_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[3];
+
+ assign s4_adr_o = m0_adr_i;
+ assign s4_sel_o = m0_sel_i;
+ assign s4_dat_o = m0_dat_i;
+ assign s4_we_o = m0_we_i;
+ assign s4_cyc_o = m0_cyc_i;
+ assign s4_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[4];
+
+ assign s5_adr_o = m0_adr_i;
+ assign s5_sel_o = m0_sel_i;
+ assign s5_dat_o = m0_dat_i;
+ assign s5_we_o = m0_we_i;
+ assign s5_cyc_o = m0_cyc_i;
+ assign s5_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[5];
+
+ assign s6_adr_o = m0_adr_i;
+ assign s6_sel_o = m0_sel_i;
+ assign s6_dat_o = m0_dat_i;
+ assign s6_we_o = m0_we_i;
+ assign s6_cyc_o = m0_cyc_i;
+ assign s6_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[6];
+
+ assign s7_adr_o = m0_adr_i;
+ assign s7_sel_o = m0_sel_i;
+ assign s7_dat_o = m0_dat_i;
+ assign s7_we_o = m0_we_i;
+ assign s7_cyc_o = m0_cyc_i;
+ assign s7_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[7];
+
+ assign s8_adr_o = m0_adr_i;
+ assign s8_sel_o = m0_sel_i;
+ assign s8_dat_o = m0_dat_i;
+ assign s8_we_o = m0_we_i;
+ assign s8_cyc_o = m0_cyc_i;
+ assign s8_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[8];
+
+ assign s9_adr_o = m0_adr_i;
+ assign s9_sel_o = m0_sel_i;
+ assign s9_dat_o = m0_dat_i;
+ assign s9_we_o = m0_we_i;
+ assign s9_cyc_o = m0_cyc_i;
+ assign s9_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[9];
+
+ assign sa_adr_o = m0_adr_i;
+ assign sa_sel_o = m0_sel_i;
+ assign sa_dat_o = m0_dat_i;
+ assign sa_we_o = m0_we_i;
+ assign sa_cyc_o = m0_cyc_i;
+ assign sa_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[10];
+
+ assign sb_adr_o = m0_adr_i;
+ assign sb_sel_o = m0_sel_i;
+ assign sb_dat_o = m0_dat_i;
+ assign sb_we_o = m0_we_i;
+ assign sb_cyc_o = m0_cyc_i;
+ assign sb_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[11];
+
+ assign sc_adr_o = m0_adr_i;
+ assign sc_sel_o = m0_sel_i;
+ assign sc_dat_o = m0_dat_i;
+ assign sc_we_o = m0_we_i;
+ assign sc_cyc_o = m0_cyc_i;
+ assign sc_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[12];
+
+ assign sd_adr_o = m0_adr_i;
+ assign sd_sel_o = m0_sel_i;
+ assign sd_dat_o = m0_dat_i;
+ assign sd_we_o = m0_we_i;
+ assign sd_cyc_o = m0_cyc_i;
+ assign sd_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[13];
+
+ assign se_adr_o = m0_adr_i;
+ assign se_sel_o = m0_sel_i;
+ assign se_dat_o = m0_dat_i;
+ assign se_we_o = m0_we_i;
+ assign se_cyc_o = m0_cyc_i;
+ assign se_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[14];
+
+ assign sf_adr_o = m0_adr_i;
+ assign sf_sel_o = m0_sel_i;
+ assign sf_dat_o = m0_dat_i;
+ assign sf_we_o = m0_we_i;
+ assign sf_cyc_o = m0_cyc_i;
+ assign sf_stb_o = m0_cyc_i & m0_stb_i & ssel_dec[15];
+
+ // Address decode logic
+ // WARNING -- must make sure these are mutually exclusive!
+
+
+ assign ssel_dec[0] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s0_addr) & s0_mask);
+ assign ssel_dec[1] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s1_addr) & s1_mask);
+ assign ssel_dec[2] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s2_addr) & s2_mask);
+ assign ssel_dec[3] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s3_addr) & s3_mask);
+ assign ssel_dec[4] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s4_addr) & s4_mask);
+ assign ssel_dec[5] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s5_addr) & s5_mask);
+ assign ssel_dec[6] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s6_addr) & s6_mask);
+ assign ssel_dec[7] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s7_addr) & s7_mask);
+ assign ssel_dec[8] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s8_addr) & s8_mask);
+ assign ssel_dec[9] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ s9_addr) & s9_mask);
+ assign ssel_dec[10] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ sa_addr) & sa_mask);
+ assign ssel_dec[11] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ sb_addr) & sb_mask);
+ assign ssel_dec[12] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ sc_addr) & sc_mask);
+ assign ssel_dec[13] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ sd_addr) & sd_mask);
+ assign ssel_dec[14] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ se_addr) & se_mask);
+ assign ssel_dec[15] = ~|((m0_adr_i[aw-1:aw-decode_w] ^ sf_addr) & sf_mask);
+
+/*
+ assign ssel_dec[0] = (m0_adr_i[aw -1 : aw - decode_w ] == s0_addr);
+ assign ssel_dec[1] = (m0_adr_i[aw -1 : aw - decode_w ] == s1_addr);
+ assign ssel_dec[2] = (m0_adr_i[aw -1 : aw - decode_w ] == s2_addr);
+ assign ssel_dec[3] = (m0_adr_i[aw -1 : aw - decode_w ] == s3_addr);
+ assign ssel_dec[4] = (m0_adr_i[aw -1 : aw - decode_w ] == s4_addr);
+ assign ssel_dec[5] = (m0_adr_i[aw -1 : aw - decode_w ] == s5_addr);
+ assign ssel_dec[6] = (m0_adr_i[aw -1 : aw - decode_w ] == s6_addr);
+ assign ssel_dec[7] = (m0_adr_i[aw -1 : aw - decode_w ] == s7_addr);
+ assign ssel_dec[8] = (m0_adr_i[aw -1 : aw - decode_w ] == s8_addr);
+ assign ssel_dec[9] = (m0_adr_i[aw -1 : aw - decode_w ] == s9_addr);
+ assign ssel_dec[10] = (m0_adr_i[aw -1 : aw - decode_w ] == sa_addr);
+ assign ssel_dec[11] = (m0_adr_i[aw -1 : aw - decode_w ] == sb_addr);
+ assign ssel_dec[12] = (m0_adr_i[aw -1 : aw - decode_w ] == sc_addr);
+ assign ssel_dec[13] = (m0_adr_i[aw -1 : aw - decode_w ] == sd_addr);
+ assign ssel_dec[14] = (m0_adr_i[aw -1 : aw - decode_w ] == se_addr);
+ assign ssel_dec[15] = (m0_adr_i[aw -1 : aw - decode_w ] == sf_addr);
+ */
+endmodule // wb_1master
diff --git a/fpga/usrp2/control_lib/wb_bridge_16_32.v b/fpga/usrp2/control_lib/wb_bridge_16_32.v
new file mode 100644
index 000000000..405e25c3c
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_bridge_16_32.v
@@ -0,0 +1,36 @@
+
+
+module wb_bridge_16_32
+ #(parameter AWIDTH=16)
+ (input wb_clk, input wb_rst,
+ input A_cyc_i, input A_stb_i, input A_we_i, input [3:0] A_sel_i,
+ input [AWIDTH-1:0] A_adr_i, input [31:0] A_dat_i, output [31:0] A_dat_o, output A_ack_o,
+ output B_cyc_o, output B_stb_o, output B_we_o, output [1:0] B_sel_o,
+ output [AWIDTH-1:0] B_adr_o, output [15:0] B_dat_o, input [15:0] B_dat_i, input B_ack_i
+ );
+
+ reg [15:0] holding;
+ reg phase;
+
+ assign B_adr_o = {A_adr_i[AWIDTH-1:2],phase,1'b0};
+ assign B_cyc_o = A_cyc_i;
+ assign B_stb_o = A_stb_i;
+ assign B_we_o = A_we_i;
+
+ assign B_dat_o = ~phase ? A_dat_i[15:0] : A_dat_i[31:16];
+ assign B_sel_o = ~phase ? A_sel_i[1:0] : A_sel_i[3:2];
+
+ assign A_dat_o = {B_dat_i,holding};
+ assign A_ack_o = phase & B_ack_i;
+
+ always @(posedge wb_clk)
+ if(wb_rst)
+ phase <= 0;
+ else if(B_ack_i)
+ phase <= ~phase;
+
+ always @(posedge wb_clk)
+ if(~phase & B_ack_i)
+ holding <= B_dat_i;
+
+endmodule // wb_bridge_16_32
diff --git a/fpga/usrp2/control_lib/wb_bus_writer.v b/fpga/usrp2/control_lib/wb_bus_writer.v
new file mode 100644
index 000000000..fc148a0ff
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_bus_writer.v
@@ -0,0 +1,57 @@
+
+// wb_bus_writer
+//
+// WB Bus Master device to send a sequence of single-word transactions
+// based on a list in a RAM or ROM (FASM interface)
+// ROM data format is {WB_ADDR[15:0],WB_DATA[31:0]}
+// continues until it gets an all-1s entry
+
+module wb_bus_writer (input start,
+ output done,
+ output reg [15:0] rom_addr,
+ input [47:0] rom_data,
+ // WB Master Interface, don't need wb_dat_i
+ input wb_clk_i,
+ input wb_rst_i,
+ output [31:0] wb_dat_o,
+ input wb_ack_i,
+ output [15:0] wb_adr_o,
+ output wb_cyc_o,
+ output [3:0] wb_sel_o,
+ output wb_stb_o,
+ output wb_we_o
+ );
+
+`define IDLE 0
+`define READ 1
+
+ reg [3:0] state;
+
+ assign done = (state != `IDLE) && (&rom_data); // Done when we see all 1s
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ begin
+ rom_addr <= #1 0;
+ state <= #1 0;
+ end
+ else if(start)
+ begin
+ rom_addr <= #1 0;
+ state <= #1 `READ;
+ end
+ else if((state == `READ) && wb_ack_i)
+ if(done)
+ state <= #1 `IDLE;
+ else
+ rom_addr <= #1 rom_addr + 1;
+
+ assign wb_dat_o = rom_data[31:0];
+ assign wb_adr_o = rom_data[47:32];
+ assign wb_sel_o = 4'b1111; // All writes are the full 32 bits
+
+ assign wb_cyc_o = !done & (state != `IDLE);
+ assign wb_stb_o = !done & (state != `IDLE);
+ assign wb_we_o = !done & (state != `IDLE);
+
+endmodule // wb_bus_writer
diff --git a/fpga/usrp2/control_lib/wb_output_pins32.v b/fpga/usrp2/control_lib/wb_output_pins32.v
new file mode 100644
index 000000000..1517f2066
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_output_pins32.v
@@ -0,0 +1,49 @@
+
+
+// Simple 32-bit Wishbone compatible slave output port
+// with 8-bit granularity, modeled after the one in the spec
+// Allows for readback
+// Assumes a 32-bit wishbone bus
+// Lowest order bits get sel[0]
+//
+
+module wb_output_pins32
+ (wb_rst_i, wb_clk_i, wb_dat_i, wb_dat_o,
+ wb_we_i, wb_sel_i, wb_stb_i, wb_ack_o, wb_cyc_i,
+ port_output);
+
+ input wb_rst_i;
+ input wb_clk_i;
+ input wire [31:0] wb_dat_i;
+ output wire [31:0] wb_dat_o;
+ input wb_we_i;
+ input wire [3:0] wb_sel_i;
+ input wb_stb_i;
+ output wb_ack_o;
+ input wb_cyc_i;
+
+ output wire [31:0] port_output;
+
+ reg [31:0] internal_reg;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ internal_reg <= #1 32'b0;
+ else
+ begin
+ if(wb_stb_i & wb_we_i & wb_sel_i[0])
+ internal_reg[7:0] <= #1 wb_dat_i[7:0];
+ if(wb_stb_i & wb_we_i & wb_sel_i[1])
+ internal_reg[15:8] <= #1 wb_dat_i[15:8];
+ if(wb_stb_i & wb_we_i & wb_sel_i[2])
+ internal_reg[23:16] <= #1 wb_dat_i[23:16];
+ if(wb_stb_i & wb_we_i & wb_sel_i[3])
+ internal_reg[31:24] <= #1 wb_dat_i[31:24];
+ end // else: !if(wb_rst_i)
+
+ assign wb_dat_o = internal_reg;
+ assign port_output = internal_reg;
+ assign wb_ack_o = wb_stb_i;
+
+endmodule // wb_output_pins32
+
diff --git a/fpga/usrp2/control_lib/wb_ram_block.v b/fpga/usrp2/control_lib/wb_ram_block.v
new file mode 100644
index 000000000..044d34ca4
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_ram_block.v
@@ -0,0 +1,36 @@
+
+
+// Since this is a block ram, there are no byte-selects and there is a 1-cycle read latency
+// These have to be a multiple of 512 lines (2K) long
+
+module wb_ram_block
+ #(parameter AWIDTH=9)
+ (input clk_i,
+ input stb_i,
+ input we_i,
+ input [AWIDTH-1:0] adr_i,
+ input [31:0] dat_i,
+ output reg [31:0] dat_o,
+ output ack_o);
+
+ reg [31:0] distram [0:1<<(AWIDTH-1)];
+
+ always @(posedge clk_i)
+ begin
+ if(stb_i & we_i)
+ distram[adr_i] <= dat_i;
+ dat_o <= distram[adr_i];
+ end
+
+ reg stb_d1, ack_d1;
+ always @(posedge clk_i)
+ stb_d1 <= stb_i;
+
+ always @(posedge clk_i)
+ ack_d1 <= ack_o;
+
+ assign ack_o = stb_i & (we_i | (stb_d1 & ~ack_d1));
+endmodule // wb_ram_block
+
+
+
diff --git a/fpga/usrp2/control_lib/wb_ram_dist.v b/fpga/usrp2/control_lib/wb_ram_dist.v
new file mode 100644
index 000000000..cffc2f423
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_ram_dist.v
@@ -0,0 +1,33 @@
+
+
+module wb_ram_dist
+ #(parameter AWIDTH=8)
+ (input clk_i,
+ input stb_i,
+ input we_i,
+ input [AWIDTH-1:0] adr_i,
+ input [31:0] dat_i,
+ input [3:0] sel_i,
+ output [31:0] dat_o,
+ output ack_o);
+
+ reg [31:0] distram [0:1<<(AWIDTH-1)];
+
+ always @(posedge clk_i)
+ begin
+ if(stb_i & we_i & sel_i[3])
+ distram[adr_i][31:24] <= dat_i[31:24];
+ if(stb_i & we_i & sel_i[2])
+ distram[adr_i][24:16] <= dat_i[24:16];
+ if(stb_i & we_i & sel_i[1])
+ distram[adr_i][15:8] <= dat_i[15:8];
+ if(stb_i & we_i & sel_i[0])
+ distram[adr_i][7:0] <= dat_i[7:0];
+ end // always @ (posedge clk_i)
+
+ assign dat_o = distram[adr_i];
+ assign ack_o = stb_i;
+
+endmodule // wb_ram_dist
+
+
diff --git a/fpga/usrp2/control_lib/wb_readback_mux.v b/fpga/usrp2/control_lib/wb_readback_mux.v
new file mode 100644
index 000000000..3922b03e3
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_readback_mux.v
@@ -0,0 +1,60 @@
+
+
+// Note -- clocks must be synchronous (derived from the same source)
+// Assumes alt_clk is running at a multiple of wb_clk
+
+module wb_readback_mux
+ (input wb_clk_i,
+ input wb_rst_i,
+ input wb_stb_i,
+ input [15:0] wb_adr_i,
+ output reg [31:0] wb_dat_o,
+ output reg wb_ack_o,
+
+ input [31:0] word00,
+ input [31:0] word01,
+ input [31:0] word02,
+ input [31:0] word03,
+ input [31:0] word04,
+ input [31:0] word05,
+ input [31:0] word06,
+ input [31:0] word07,
+ input [31:0] word08,
+ input [31:0] word09,
+ input [31:0] word10,
+ input [31:0] word11,
+ input [31:0] word12,
+ input [31:0] word13,
+ input [31:0] word14,
+ input [31:0] word15
+ );
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ wb_ack_o <= 0;
+ else
+ wb_ack_o <= wb_stb_i & ~wb_ack_o;
+
+ always @(posedge wb_clk_i)
+ case(wb_adr_i[5:2])
+ 0 : wb_dat_o <= word00;
+ 1 : wb_dat_o <= word01;
+ 2 : wb_dat_o <= word02;
+ 3 : wb_dat_o <= word03;
+ 4 : wb_dat_o <= word04;
+ 5 : wb_dat_o <= word05;
+ 6 : wb_dat_o <= word06;
+ 7 : wb_dat_o <= word07;
+ 8 : wb_dat_o <= word08;
+ 9 : wb_dat_o <= word09;
+ 10: wb_dat_o <= word10;
+ 11: wb_dat_o <= word11;
+ 12: wb_dat_o <= word12;
+ 13: wb_dat_o <= word13;
+ 14: wb_dat_o <= word14;
+ 15: wb_dat_o <= word15;
+ endcase // case(addr_reg[3:0])
+
+endmodule // wb_readback_mux
+
+
diff --git a/fpga/usrp2/control_lib/wb_regfile_2clock.v b/fpga/usrp2/control_lib/wb_regfile_2clock.v
new file mode 100644
index 000000000..e248e5161
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_regfile_2clock.v
@@ -0,0 +1,107 @@
+
+module wb_regfile_2clock
+ (input wb_clk_i,
+ input wb_rst_i,
+ input wb_stb_i,
+ input wb_we_i,
+ input [15:0] wb_adr_i,
+ input [3:0] wb_sel_i,
+ input [31:0] wb_dat_i,
+ output [31:0] wb_dat_o,
+ output wb_ack_o,
+ input alt_clk,
+ input alt_rst,
+
+ output reg [31:0] reg00,
+ output reg [31:0] reg01,
+ output reg [31:0] reg02,
+ output reg [31:0] reg03,
+ output reg [31:0] reg04,
+ output reg [31:0] reg05,
+ output reg [31:0] reg06,
+ output reg [31:0] reg07
+ );
+
+ reg [15:0] addr_reg;
+ reg [3:0] sel_reg;
+ reg [31:0] dat_reg;
+ reg wr_ret1, wr_ret2, we_reg, stb_reg;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ begin
+ addr_reg <= 0;
+ sel_reg <= 0;
+ dat_reg <= 0;
+ end
+ else if(wb_stb_i & wb_we_i)
+ begin
+ addr_reg <= wb_adr_i;
+ sel_reg <= wb_sel_i;
+ dat_reg <= wb_dat_i;
+ end
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ {we_reg,stb_reg} <= 2'b0;
+ else
+ {we_reg,stb_reg} <= {wb_we_i,wb_stb_i};
+
+ assign wb_ack_o = stb_reg;
+
+ always @(posedge alt_clk)
+ if(alt_rst)
+ {wr_ret2, wr_ret1} <= 2'b0;
+ else
+ {wr_ret2, wr_ret1} <= {wr_ret1, we_reg & stb_reg};
+
+ always @(posedge alt_clk)
+ if(alt_rst)
+ begin
+ reg00 <= 0;
+ reg01 <= 0;
+ reg02 <= 0;
+ reg03 <= 0;
+ reg04 <= 0;
+ reg05 <= 0;
+ reg06 <= 0;
+ reg07 <= 0;
+ end // if (alt_rst)
+ else if(wr_ret2)
+ case(addr_reg[4:2])
+ 3'd0: reg00 <= { {sel_reg[3] ? dat_reg[31:24] : reg00[31:24]},
+ {sel_reg[2] ? dat_reg[23:16] : reg00[23:16]},
+ {sel_reg[1] ? dat_reg[15:8] : reg00[15:8]},
+ {sel_reg[0] ? dat_reg[7:0] : reg00[7:0]}};
+ 3'd1: reg01 <= { {sel_reg[3] ? dat_reg[31:24] : reg01[31:24]},
+ {sel_reg[2] ? dat_reg[23:16] : reg01[23:16]},
+ {sel_reg[1] ? dat_reg[15:8] : reg01[15:8]},
+ {sel_reg[0] ? dat_reg[7:0] : reg01[7:0]}};
+ 3'd2: reg02 <= { {sel_reg[3] ? dat_reg[31:24] : reg02[31:24]},
+ {sel_reg[2] ? dat_reg[23:16] : reg02[23:16]},
+ {sel_reg[1] ? dat_reg[15:8] : reg02[15:8]},
+ {sel_reg[0] ? dat_reg[7:0] : reg02[7:0]}};
+ 3'd3: reg03 <= { {sel_reg[3] ? dat_reg[31:24] : reg03[31:24]},
+ {sel_reg[2] ? dat_reg[23:16] : reg03[23:16]},
+ {sel_reg[1] ? dat_reg[15:8] : reg03[15:8]},
+ {sel_reg[0] ? dat_reg[7:0] : reg03[7:0]}};
+ 3'd4: reg04 <= { {sel_reg[3] ? dat_reg[31:24] : reg04[31:24]},
+ {sel_reg[2] ? dat_reg[23:16] : reg04[23:16]},
+ {sel_reg[1] ? dat_reg[15:8] : reg04[15:8]},
+ {sel_reg[0] ? dat_reg[7:0] : reg04[7:0]}};
+ 3'd5: reg05 <= { {sel_reg[3] ? dat_reg[31:24] : reg05[31:24]},
+ {sel_reg[2] ? dat_reg[23:16] : reg05[23:16]},
+ {sel_reg[1] ? dat_reg[15:8] : reg05[15:8]},
+ {sel_reg[0] ? dat_reg[7:0] : reg05[7:0]}};
+ 3'd6: reg06 <= { {sel_reg[3] ? dat_reg[31:24] : reg06[31:24]},
+ {sel_reg[2] ? dat_reg[23:16] : reg06[23:16]},
+ {sel_reg[1] ? dat_reg[15:8] : reg06[15:8]},
+ {sel_reg[0] ? dat_reg[7:0] : reg06[7:0]}};
+ 3'd7: reg07 <= { {sel_reg[3] ? dat_reg[31:24] : reg07[31:24]},
+ {sel_reg[2] ? dat_reg[23:16] : reg07[23:16]},
+ {sel_reg[1] ? dat_reg[15:8] : reg07[15:8]},
+ {sel_reg[0] ? dat_reg[7:0] : reg07[7:0]}};
+ endcase // case(addr_reg[2:0])
+
+endmodule // wb_regfile_2clock
+
diff --git a/fpga/usrp2/control_lib/wb_semaphore.v b/fpga/usrp2/control_lib/wb_semaphore.v
new file mode 100644
index 000000000..a9208e6a1
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_semaphore.v
@@ -0,0 +1,42 @@
+
+// up to 8 semaphores
+
+// After a read operation, the semaphore is always locked
+// If it was already locked before the read (meaning someone else holds the lock)
+// then a 1 is returned
+// If it was not already locked (meaning the reader now holds the lock)
+// then a 0 is returned
+
+// A write operation clears the lock
+
+module wb_semaphore
+ #(parameter count=8, DBUS_WIDTH=32)
+ (input wb_clk_i,
+ input wb_rst_i,
+ input [DBUS_WIDTH-1:0] wb_dat_i,
+ input [2:0] wb_adr_i,
+ input wb_cyc_i,
+ input wb_stb_i,
+ input wb_we_i,
+ output wb_ack_o,
+ output [DBUS_WIDTH-1:0] wb_dat_o);
+
+ reg [count-1:0] locked;
+
+ always @(posedge clock)
+ if(wb_rst_i)
+ locked <= {count{1'b0}};
+ else if(wb_stb_i)
+ if(wb_we_i)
+ locked[adr_i] <= 1'b0;
+ else
+ locked[adr_i] <= 1'b1;
+
+ assign wb_dat_o[DBUS_WIDTH-1:1] = {(DBUS_WIDTH-1){1'b0}};
+ assign wb_dat_o[0] = locked[adr_i];
+ assign wb_ack_o = wb_stb_i;
+
+
+endmodule // wb_semaphore
+
+
diff --git a/fpga/usrp2/control_lib/wb_sim.v b/fpga/usrp2/control_lib/wb_sim.v
new file mode 100644
index 000000000..b324e1457
--- /dev/null
+++ b/fpga/usrp2/control_lib/wb_sim.v
@@ -0,0 +1,79 @@
+
+
+module wb_sim();
+
+ wire wb_clk, wb_rst;
+ wire start;
+
+ reg POR, aux_clk, clk_fpga;
+
+ initial POR = 1'b1;
+ initial #103 POR = 1'b0;
+
+ initial aux_clk = 1'b0;
+ always #25 aux_clk = ~aux_clk;
+
+ initial clk_fpga = 1'bx;
+ initial #3007 clk_fpga = 1'b0;
+ always #7 clk_fpga = ~clk_fpga;
+
+ initial begin
+ $dumpfile("wb_sim.vcd");
+ $dumpvars(0,wb_sim);
+ end
+
+ initial #10000 $finish;
+
+ wire [15:0] rom_addr;
+ wire [47:0] rom_data;
+ wire [31:0] wb_dat;
+ wire [15:0] wb_adr;
+ wire wb_cyc,wb_stb,wb_we,wb_ack;
+ wire [3:0] wb_sel;
+
+ wire [31:0] port_output;
+
+
+ system_control system_control(.dsp_clk(dsp_clk),
+ .reset_out(reset_out),
+ .wb_clk_o(wb_clk),
+ .wb_rst_o(wb_rst),
+ .wb_rst_o_alt(wb_rst_o_alt),
+ .start (start),
+ .aux_clk(aux_clk),
+ .clk_fpga(clk_fpga),
+ .POR (POR),
+ .done (done));
+
+ clock_bootstrap_rom cbrom(.addr(rom_addr),.data(rom_data));
+
+ wb_bus_writer bus_writer(.rom_addr (rom_addr[15:0]),
+ .wb_dat_o (wb_dat[31:0]),
+ .wb_adr_o (wb_adr[15:0]),
+ .wb_cyc_o (wb_cyc),
+ .wb_sel_o (wb_sel[3:0]),
+ .wb_stb_o (wb_stb),
+ .wb_we_o (wb_we),
+ .start (start),
+ .done (done),
+ .rom_data (rom_data[47:0]),
+ .wb_clk_i (wb_clk),
+ .wb_rst_i (wb_rst),
+ .wb_ack_i (wb_ack));
+
+ wb_output_pins32 output_pins(.wb_dat_o(),
+ .wb_ack_o(wb_ack),
+ .port_output(port_output[31:0]),
+ .wb_rst_i(wb_rst),
+ .wb_clk_i(wb_clk),
+ .wb_dat_i(wb_dat[31:0]),
+ .wb_we_i(wb_we),
+ .wb_sel_i(wb_sel[3:0]),
+ .wb_stb_i(wb_stb),
+ .wb_cyc_i(wb_cyc));
+
+
+
+
+endmodule // wb_sim
+