diff options
Diffstat (limited to 'fpga/usrp2')
27 files changed, 1342 insertions, 372 deletions
| diff --git a/fpga/usrp2/control_lib/Makefile.srcs b/fpga/usrp2/control_lib/Makefile.srcs index a1c11c026..567feacde 100644 --- a/fpga/usrp2/control_lib/Makefile.srcs +++ b/fpga/usrp2/control_lib/Makefile.srcs @@ -11,7 +11,9 @@ atr_controller.v \  bin2gray.v \  dcache.v \  decoder_3_8.v \ +dbsm.v \  dpram32.v \ +double_buffer.v \  gray2bin.v \  gray_send.v \  icache.v \ @@ -51,4 +53,5 @@ nsgpio16LE.v \  settings_bus_16LE.v \  atr_controller16.v \  fifo_to_wb.v \ +gpio_atr.v \  )) diff --git a/fpga/usrp2/control_lib/dbsm.v b/fpga/usrp2/control_lib/dbsm.v new file mode 100644 index 000000000..fea51096f --- /dev/null +++ b/fpga/usrp2/control_lib/dbsm.v @@ -0,0 +1,164 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +module dbsm +  (input clk, +   input reset, +   input clear, +    +   output write_ok, +   output write_ptr, +   input write_done, + +   output read_ok, +   output read_ptr, +   input read_done, + +   output access_ok, +   output access_ptr, +   input access_done, +   input access_skip_read +   ); + +   localparam PORT_WAIT_0 = 0; +   localparam PORT_USE_0 = 1; +   localparam PORT_WAIT_1 = 2; +   localparam PORT_USE_1 = 3; + +   reg [1:0] write_port_state, access_port_state, read_port_state; + +   localparam BUFF_WRITABLE = 0; +   localparam BUFF_ACCESSIBLE = 1; +   localparam BUFF_READABLE = 2; +   localparam BUFF_ERROR = 3; + +   wire [1:0] buff_state[0:1]; +    +   always @(posedge clk) +     if(reset | clear) +       write_port_state <= PORT_WAIT_0; +     else +       case(write_port_state) +	 PORT_WAIT_0 : +	   if(buff_state[0]==BUFF_WRITABLE) +	     write_port_state <= PORT_USE_0; +	 PORT_USE_0 : +	   if(write_done) +	     write_port_state <= PORT_WAIT_1; +	 PORT_WAIT_1 : +	   if(buff_state[1]==BUFF_WRITABLE) +	     write_port_state <= PORT_USE_1; +	 PORT_USE_1 : +	   if(write_done) +	     write_port_state <= PORT_WAIT_0; +       endcase // case (write_port_state) + +   assign write_ok = (write_port_state == PORT_USE_0) | (write_port_state == PORT_USE_1); +   assign write_ptr = (write_port_state == PORT_USE_1); +    +   always @(posedge clk) +     if(reset | clear) +       access_port_state <= PORT_WAIT_0; +     else +       case(access_port_state) +	 PORT_WAIT_0 : +	   if(buff_state[0]==BUFF_ACCESSIBLE) +	     access_port_state <= PORT_USE_0; +	 PORT_USE_0 : +	   if(access_done) +	     access_port_state <= PORT_WAIT_1; +	 PORT_WAIT_1 : +	   if(buff_state[1]==BUFF_ACCESSIBLE) +	     access_port_state <= PORT_USE_1; +	 PORT_USE_1 : +	   if(access_done) +	     access_port_state <= PORT_WAIT_0; +       endcase // case (access_port_state) +    +   assign access_ok = (access_port_state == PORT_USE_0) | (access_port_state == PORT_USE_1); +   assign access_ptr = (access_port_state == PORT_USE_1); + +   always @(posedge clk) +     if(reset | clear) +       read_port_state <= PORT_WAIT_0; +     else +       case(read_port_state) +	 PORT_WAIT_0 : +	   if(buff_state[0]==BUFF_READABLE) +	     read_port_state <= PORT_USE_0; +	 PORT_USE_0 : +	   if(read_done) +	     read_port_state <= PORT_WAIT_1; +	 PORT_WAIT_1 : +	   if(buff_state[1]==BUFF_READABLE) +	     read_port_state <= PORT_USE_1; +	 PORT_USE_1 : +	   if(read_done) +	     read_port_state <= PORT_WAIT_0; +       endcase // case (read_port_state) +    +   assign read_ok = (read_port_state == PORT_USE_0) | (read_port_state == PORT_USE_1); +   assign read_ptr = (read_port_state == PORT_USE_1); + +   buff_sm #(.PORT_USE_FLAG(PORT_USE_0)) buff0_sm +     (.clk(clk), .reset(reset), .clear(clear), +      .write_done(write_done), .access_done(access_done), .access_skip_read(access_skip_read), .read_done(read_done), +      .write_port_state(write_port_state), .access_port_state(access_port_state), .read_port_state(read_port_state), +      .buff_state(buff_state[0])); +    +   buff_sm #(.PORT_USE_FLAG(PORT_USE_1)) buff1_sm +     (.clk(clk), .reset(reset), .clear(clear), +      .write_done(write_done), .access_done(access_done), .access_skip_read(access_skip_read), .read_done(read_done), +      .write_port_state(write_port_state), .access_port_state(access_port_state), .read_port_state(read_port_state), +      .buff_state(buff_state[1])); +    +endmodule // dbsm + +module buff_sm +  #(parameter PORT_USE_FLAG=0) +   (input clk, input reset, input clear, +    input write_done, input access_done, input access_skip_read, input read_done, +    input [1:0] write_port_state, input [1:0] access_port_state, input [1:0] read_port_state, +    output reg [1:0] buff_state); +    +   localparam BUFF_WRITABLE = 0; +   localparam BUFF_ACCESSIBLE = 1; +   localparam BUFF_READABLE = 2; +   localparam BUFF_ERROR = 3; + +   always @(posedge clk) +     if(reset | clear) +       buff_state <= BUFF_WRITABLE; +     else +       case(buff_state) +	 BUFF_WRITABLE : +	   if(write_done & (write_port_state == PORT_USE_FLAG)) +	     buff_state <= BUFF_ACCESSIBLE; +	 BUFF_ACCESSIBLE : +	   if(access_done & (access_port_state == PORT_USE_FLAG)) +	     if(access_skip_read) +	       buff_state <= BUFF_WRITABLE; +	     else +	       buff_state <= BUFF_READABLE; +	 BUFF_READABLE : +	   if(read_done & (read_port_state == PORT_USE_FLAG)) +	     buff_state <= BUFF_WRITABLE; +	 BUFF_ERROR : +	   ; +       endcase +	  +endmodule // buff_sm diff --git a/fpga/usrp2/control_lib/double_buffer.v b/fpga/usrp2/control_lib/double_buffer.v new file mode 100644 index 000000000..8865bddee --- /dev/null +++ b/fpga/usrp2/control_lib/double_buffer.v @@ -0,0 +1,139 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +module double_buffer +  #(parameter BUF_SIZE = 9) +   (input clk, input reset, input clear, + +    // Random access interface to RAM +    input access_we, +    input access_stb, +    output access_ok, +    input access_done, +    input access_skip_read, +    input [BUF_SIZE-1:0] access_adr, +    output [BUF_SIZE-1:0] access_len, +    input [35:0] access_dat_i,    +    output [35:0] access_dat_o, +     +    // Write FIFO Interface +    input [35:0] data_i, +    input src_rdy_i, +    output dst_rdy_o, +     +    // Read FIFO Interface +    output [35:0] data_o, +    output src_rdy_o, +    input dst_rdy_i +    ); + +   wire [35:0] data_o_0, data_o_1; + +   wire        read, read_ok, read_ptr, read_done; +   wire        write, write_ok, write_ptr, write_done; +    +   wire [BUF_SIZE-1:0] rw0_adr, rw1_adr; +   reg [BUF_SIZE-1:0]  read_adr, write_adr; +   reg [BUF_SIZE-1:0]  len0, len1; +  +   assign data_o = read_ptr ? data_o_1 : data_o_0; +   assign rw0_adr = (write_ok & ~write_ptr) ? write_adr : read_adr; +   assign rw1_adr = (write_ok & write_ptr) ? write_adr : read_adr; +    +   wire [35:0] 	       access_dat_o_0, access_dat_o_1; +   wire 	       access_ptr; +   assign access_dat_o = access_ptr? access_dat_o_1 : access_dat_o_0; +    +   dbsm dbsm  +     (.clk(clk), .reset(reset), .clear(clear), +      .write_ok(write_ok), .write_ptr(write_ptr), .write_done(write_done), +      .access_ok(access_ok), .access_ptr(access_ptr), .access_done(access_done), .access_skip_read(access_skip_read), +      .read_ok(read_ok), .read_ptr(read_ptr), .read_done(read_done)); +    +   // Port A for random access, Port B for FIFO read and write +   ram_2port #(.DWIDTH(36),.AWIDTH(BUF_SIZE)) buffer0 +     (.clka(clk),.ena(access_stb & access_ok & (access_ptr == 0)),.wea(access_we), +      .addra(access_adr),.dia(access_dat_i),.doa(access_dat_o_0), +      .clkb(clk),.enb((read & read_ok & ~read_ptr)|(write & write_ok & ~write_ptr) ),.web(write&write_ok&~write_ptr), +      .addrb(rw0_adr),.dib(data_i),.dob(data_o_0)); +    +   ram_2port #(.DWIDTH(36),.AWIDTH(BUF_SIZE)) buffer1 +     (.clka(clk),.ena(access_stb & access_ok & (access_ptr == 1)),.wea(access_we), +      .addra(access_adr),.dia(access_dat_i),.doa(access_dat_o_1), +      .clkb(clk),.enb((read & read_ok & read_ptr)|(write & write_ok & write_ptr) ),.web(write&write_ok&write_ptr), +      .addrb(rw1_adr),.dib(data_i),.dob(data_o_1)); + +   // Write into buffers +   assign dst_rdy_o =  write_ok; +   assign write = src_rdy_i & write_ok; +   assign write_done = write & data_i[33]; // done +   always @(posedge clk) +     if(reset | clear) +       write_adr <= 0; +     else +       if(write_done) +	 begin +	    write_adr <= 0; +	    if(write_ptr) +	      len1 <= write_adr + 1; +	    else +	      len0 <= write_adr + 1; +	 end +       else if(write) +	 write_adr <= write_adr + 1; + +   assign access_len = access_ptr ? len1 : len0; +    +   reg [1:0] 	       read_state; +   localparam IDLE = 0; +   localparam PRE_READ = 1; +   localparam READING = 2; +    +   always @(posedge clk) +     if(reset | clear) +       begin +	  read_state <= IDLE; +	  read_adr <= 0; +       end +     else +       case(read_state) +	 IDLE : +	   begin +	      read_adr <= 0; +	      if(read_ok) +		read_state <= PRE_READ; +	   end +	 PRE_READ : +	   begin +	      read_state <= READING; +	      read_adr <= 1; +	   end +	  +	 READING : +	   if(dst_rdy_i) +	     begin +		read_adr <= read_adr + 1; +		if(data_o[33]) +		  read_state <= IDLE; +	     end +       endcase // case (read_state) +       +   assign read = ~((read_state==READING)& ~dst_rdy_i); +   assign read_done = data_o[33] & dst_rdy_i & src_rdy_o; +   assign src_rdy_o = (read_state == READING); +    +endmodule // double_buffer diff --git a/fpga/usrp2/control_lib/double_buffer_tb.v b/fpga/usrp2/control_lib/double_buffer_tb.v new file mode 100644 index 000000000..a9aae6956 --- /dev/null +++ b/fpga/usrp2/control_lib/double_buffer_tb.v @@ -0,0 +1,253 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +module double_buffer_tb(); +    +   reg clk = 0; +   reg rst = 1; +   reg clear = 0; +   initial #1000 rst = 0; +   always #50 clk = ~clk; + +   wire src_rdy_o; +   reg src_rdy_i = 0; +   wire dst_rdy_o; +    +   wire dst_rdy_i = 1; +   wire [35:0] data_o; +   reg [35:0]  data_i; + +   wire        access_we, access_stb, access_done, access_ok, access_skip_read; + +   wire [8:0]  access_adr, access_len; +   wire [35:0] dsp_to_buf, buf_to_dsp; +   reg 	       set_stb = 0; +    +   double_buffer db +     (.clk(clk),.reset(rst),.clear(0), +      .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +      .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +      .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), + +      .data_i(data_i), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), +      .data_o(data_o), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); + +   dspengine_16to8 dspengine_16to8 +     (.clk(clk),.reset(rst),.clear(0), +      .set_stb(set_stb), .set_addr(0), .set_data({13'h0,1'b1,18'h00400}), +      .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +      .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +      .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); +    +   always @(posedge clk) +     if(src_rdy_o & dst_rdy_i) +       begin +	  $display("SOF %d, EOF %d, OCC %x, DAT %x",data_o[32],data_o[33],data_o[35:34],data_o[31:0]); +	  if(data_o[33]) +	    $display(); +       end	   +   initial $dumpfile("double_buffer_tb.vcd"); +   initial $dumpvars(0,double_buffer_tb); + +   initial +     begin +	@(negedge rst); +	@(posedge clk); +	@(posedge clk); +	@(posedge clk); + +	// Passthrough +	$display("Passthrough"); +	src_rdy_i <= 1; +	data_i <= { 2'b00,1'b0,1'b1,32'hFFFFFFFF}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h04050607}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h08090a0b}; +	@(posedge clk); +	data_i <= { 2'b00,1'b1,1'b0,32'h0c0d0e0f}; +	@(posedge clk); +	src_rdy_i <= 0; +	@(posedge clk); + +	repeat (5) +	  @(posedge clk); + +	$display("Enabled"); +	set_stb <= 1; +	@(posedge clk); +	set_stb <= 0; + +	@(posedge clk); +	$display("Non-IF Data Passthrough"); +	src_rdy_i <= 1; +	data_i <= { 2'b00,1'b0,1'b1,32'hC0000000}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h14151617}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h18191a1b}; +	@(posedge clk); +	data_i <= { 2'b00,1'b1,1'b0,32'h1c1d1e1f}; +	@(posedge clk); +	src_rdy_i <= 0; +	@(posedge clk); + +	while(~dst_rdy_o) +	  @(posedge clk); +	 +	$display("No StreamID, No Trailer, Even"); +	src_rdy_i <= 1; +  	data_i <= { 2'b00,1'b0,1'b1,32'h0000FFFF}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h01000200}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h03000400}; +	src_rdy_i <= 0; +	@(posedge clk); +	@(posedge clk); +	@(posedge clk); +	@(posedge clk); +	src_rdy_i <= 1; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h05000600}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h07000800}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h09000a00}; +  	@(posedge clk); +	data_i <= { 2'b00,1'b1,1'b0,32'h0b000c00}; +	@(posedge clk); +	src_rdy_i <= 0; +	@(posedge clk); + +	while(~dst_rdy_o) +	  @(posedge clk); + +	$display("No StreamID, No Trailer, Odd"); +	src_rdy_i <= 1; +  	data_i <= { 2'b00,1'b0,1'b1,32'h0000FFFF}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h11001200}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h13001400}; +	src_rdy_i <= 0; +	@(posedge clk); +	src_rdy_i <= 1; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h15001600}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h17001800}; +	@(posedge clk); +	data_i <= { 2'b00,1'b1,1'b0,32'h19001a00}; +	@(posedge clk); +	src_rdy_i <= 0; +	@(posedge clk); + +	while(~dst_rdy_o) +	  @(posedge clk); + +	$display("No StreamID, Trailer, Even"); +	src_rdy_i <= 1; +  	data_i <= { 2'b00,1'b0,1'b1,32'h0400FFFF}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h21002200}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h23002400}; +	src_rdy_i <= 0; +	@(posedge clk); +	src_rdy_i <= 1; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h25002600}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h27002800}; +	@(posedge clk); +	data_i <= { 2'b00,1'b1,1'b0,32'h29002a00}; +	@(posedge clk); +	src_rdy_i <= 0; +	@(posedge clk); + +	while(~dst_rdy_o) +	  @(posedge clk); + +	$display("No StreamID, Trailer, Odd"); +	src_rdy_i <= 1; +  	data_i <= { 2'b00,1'b0,1'b1,32'h0400FFFF}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h31003200}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h33003400}; +	src_rdy_i <= 0; +	@(posedge clk); +	src_rdy_i <= 1; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h35003600}; +	@(posedge clk); +	data_i <= { 2'b00,1'b1,1'b0,32'h39003a00}; +	@(posedge clk); +	src_rdy_i <= 0; +	@(posedge clk); + +	while(~dst_rdy_o) +	  @(posedge clk); + +	$display("StreamID, No Trailer, Even"); +	src_rdy_i <= 1; +  	data_i <= { 2'b00,1'b0,1'b1,32'h1000FFFF}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h11001200}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h13001400}; +	src_rdy_i <= 0; +	@(posedge clk); +	src_rdy_i <= 1; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h15001600}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'h17001800}; +	@(posedge clk); +	data_i <= { 2'b00,1'b1,1'b0,32'h19001a00}; +	@(posedge clk); +	src_rdy_i <= 0; +	@(posedge clk); + +	while(~dst_rdy_o) +	  @(posedge clk); + +	$display("StreamID, Trailer, Odd"); +	src_rdy_i <= 1; +  	data_i <= { 2'b00,1'b0,1'b1,32'h1400FFFF}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'ha100a200}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'ha300a400}; +	src_rdy_i <= 0; +	@(posedge clk); +	src_rdy_i <= 1; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'ha500a600}; +	@(posedge clk); +	data_i <= { 2'b00,1'b0,1'b0,32'ha700a800}; +	@(posedge clk); +	data_i <= { 2'b00,1'b1,1'b0,32'hbbb0bbb0}; +	@(posedge clk); +	src_rdy_i <= 0; +	@(posedge clk); + +     end +    +   initial #28000 $finish; +endmodule // double_buffer_tb diff --git a/fpga/usrp2/control_lib/gpio_atr.v b/fpga/usrp2/control_lib/gpio_atr.v new file mode 100644 index 000000000..82d72b815 --- /dev/null +++ b/fpga/usrp2/control_lib/gpio_atr.v @@ -0,0 +1,71 @@ + +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + + +module gpio_atr +  #(parameter BASE = 0, +    parameter WIDTH = 32) +   (input clk, input reset, +    input set_stb, input [7:0] set_addr, input [31:0] set_data, +    input rx, input tx, +    inout [WIDTH-1:0] gpio, +    output reg [31:0] gpio_readback +    ); +    +   wire [WIDTH-1:0]   ddr, in_idle, in_tx, in_rx, in_fdx; +   reg [WIDTH-1:0]    rgpio, igpio; +    +   setting_reg #(.my_addr(BASE+0), .width(WIDTH)) reg_idle +     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data), +      .out(in_idle),.changed()); + +   setting_reg #(.my_addr(BASE+1), .width(WIDTH)) reg_rx +     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data), +      .out(in_rx),.changed()); + +   setting_reg #(.my_addr(BASE+2), .width(WIDTH)) reg_tx +     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data), +      .out(in_tx),.changed()); + +   setting_reg #(.my_addr(BASE+3), .width(WIDTH)) reg_fdx +     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data), +      .out(in_fdx),.changed()); + +   setting_reg #(.my_addr(BASE+4), .width(WIDTH)) reg_ddr +     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data), +      .out(ddr),.changed()); + +   always @(posedge clk) +     case({tx,rx}) +       2'b00: rgpio <= in_idle; +       2'b01: rgpio <= in_rx; +       2'b10: rgpio <= in_tx; +       2'b11: rgpio <= in_fdx; +     endcase // case ({tx,rx}) +    +   integer 	      n; +   always @* +     for(n=0;n<WIDTH;n=n+1) +       igpio[n] <= ddr[n] ? rgpio[n] : 1'bz; + +   assign     gpio = igpio; + +   always @(posedge clk) +     gpio_readback <= gpio; +    +endmodule // gpio_atr diff --git a/fpga/usrp2/fifo/Makefile.srcs b/fpga/usrp2/fifo/Makefile.srcs index 02c567049..28d506571 100644 --- a/fpga/usrp2/fifo/Makefile.srcs +++ b/fpga/usrp2/fifo/Makefile.srcs @@ -6,6 +6,7 @@  # FIFO Sources  ##################################################  FIFO_SRCS = $(abspath $(addprefix $(BASE_DIR)/../fifo/, \ +add_routing_header.v \  buffer_int.v \  buffer_int2.v \  buffer_pool.v \ diff --git a/fpga/usrp2/fifo/add_routing_header.v b/fpga/usrp2/fifo/add_routing_header.v new file mode 100644 index 000000000..ee6a635f5 --- /dev/null +++ b/fpga/usrp2/fifo/add_routing_header.v @@ -0,0 +1,47 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +module add_routing_header +  #(parameter PORT_SEL = 0, +    parameter PROT_ENG_FLAGS = 1) +   (input clk, input reset, input clear, +    input [35:0] data_i, input src_rdy_i, output dst_rdy_o, +    output [35:0] data_o, output src_rdy_o, input dst_rdy_i); + +   reg [1:0] 	  line; +   wire [1:0] 	  port_sel_bits = PORT_SEL; +   wire [15:0] 	  len = data_i[15:0]; +    +   always @(posedge clk) +     if(reset) +       line <= PROT_ENG_FLAGS ? 0 : 1; +     else +       if(src_rdy_o & dst_rdy_i) +	 if(data_o[33]) +	   line <= PROT_ENG_FLAGS ? 0 : 1; +	 else +	   if(line != 3) +	     line <= line + 1; + +   assign data_o = (line == 0) ? {4'b0001, 13'b0, port_sel_bits, 1'b1, len[13:0],2'b00} : +		   (line == 1) ? {3'b000, (PROT_ENG_FLAGS ? 1'b0: 1'b1), data_i[31:0]} :  +		   data_i[35:0]; + +   assign dst_rdy_o = dst_rdy_i & (line != 0); +   assign src_rdy_o = src_rdy_i; +    +endmodule // add_routing_header diff --git a/fpga/usrp2/gpif/gpif.v b/fpga/usrp2/gpif/gpif.v index 51d6e8ba9..e5b63d5a3 100644 --- a/fpga/usrp2/gpif/gpif.v +++ b/fpga/usrp2/gpif/gpif.v @@ -37,10 +37,13 @@ module gpif      input [35:0] tx_err_data_i, input tx_err_src_rdy_i, output tx_err_dst_rdy_o,      output tx_underrun, output rx_overrun, -    input [7:0] frames_per_packet, input [15:0] test_len, input [7:0] test_rate, input [3:0] test_ctrl, +    input [7:0] frames_per_packet,      output [31:0] debug0, output [31:0] debug1      ); +   assign tx_underrun = 0; +   assign rx_overrun = 0; +        wire 	  WR = gpif_ctl[0];     wire 	  RD = gpif_ctl[1];     wire 	  OE = gpif_ctl[2]; @@ -62,8 +65,8 @@ module gpif     wire [18:0] 	  tx19_data;     wire 	  tx19_src_rdy, tx19_dst_rdy; -   wire [35:0] 	  tx36_data, tx_data; -   wire 	  tx36_src_rdy, tx36_dst_rdy, tx_src_rdy, tx_dst_rdy; +   wire [35:0] 	  tx36_data; +   wire 	  tx36_src_rdy, tx36_dst_rdy;     wire [18:0] 	  ctrl_data;     wire 	  ctrl_src_rdy, ctrl_dst_rdy; @@ -95,13 +98,13 @@ module gpif     fifo_cascade #(.WIDTH(36), .SIZE(TXFIFOSIZE)) tx_fifo36       (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx),        .datain(tx36_data), .src_rdy_i(tx36_src_rdy), .dst_rdy_o(tx36_dst_rdy), -      .dataout(tx_data), .src_rdy_o(tx_src_rdy), .dst_rdy_i(tx_dst_rdy)); +      .dataout(tx_data_o), .src_rdy_o(tx_src_rdy_o), .dst_rdy_i(tx_dst_rdy_i));     // ////////////////////////////////////////////     // RX Data Path -   wire [35:0] 	  rx36_data, rx_data; -   wire 	  rx36_src_rdy, rx36_dst_rdy, rx_src_rdy, rx_dst_rdy; +   wire [35:0] 	  rx36_data; +   wire 	  rx36_src_rdy, rx36_dst_rdy;     wire [18:0] 	  rx19_data, splt_data;     wire 	  rx19_src_rdy, rx19_dst_rdy, splt_src_rdy, splt_dst_rdy;     wire [18:0] 	  resp_data, resp_int1, resp_int2; @@ -110,7 +113,7 @@ module gpif     fifo_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_fifo36       (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .datain(rx_data), .src_rdy_i(rx_src_rdy), .dst_rdy_o(rx_dst_rdy), +      .datain(rx_data_i), .src_rdy_i(rx_src_rdy_i), .dst_rdy_o(rx_dst_rdy_o),        .dataout(rx36_data), .src_rdy_o(rx36_src_rdy), .dst_rdy_i(rx36_dst_rdy));     fifo36_to_fifo19 #(.LE(1)) f36_to_f19 @@ -166,81 +169,6 @@ module gpif        .data_i(resp_int2), .src_rdy_i(resp_src_rdy_int2), .dst_rdy_o(resp_dst_rdy_int2),        .data_o(resp_data), .src_rdy_o(resp_src_rdy), .dst_rdy_i(resp_dst_rdy)); -   // //////////////////////////////////////////////////////////////////// -   // Debug support, timed and loopback -   // RX side muxes test data into the same stream -   wire [35:0] 	timedrx_data, loopbackrx_data, testrx_data; -   wire [35:0] 	timedtx_data, loopbacktx_data, testtx_data; -   wire 	timedrx_src_rdy, timedrx_dst_rdy, loopbackrx_src_rdy, loopbackrx_dst_rdy, -		testrx_src_rdy, testrx_dst_rdy; -   wire 	timedtx_src_rdy, timedtx_dst_rdy, loopbacktx_src_rdy, loopbacktx_dst_rdy, -		testtx_src_rdy, testtx_dst_rdy; -   wire 	timedrx_src_rdy_int, timedrx_dst_rdy_int, timedtx_src_rdy_int, timedtx_dst_rdy_int; - -   wire [31:0] 	total, crc_err, seq_err, len_err; -   wire 	sel_testtx = test_ctrl[0]; -   wire 	sel_loopbacktx = test_ctrl[1]; -   wire 	pkt_src_enable = test_ctrl[2]; -   wire 	pkt_sink_enable = test_ctrl[3]; -    -   fifo36_mux rx_test_mux_lvl_1 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .data0_i(timedrx_data), .src0_rdy_i(timedrx_src_rdy), .dst0_rdy_o(timedrx_dst_rdy), -      .data1_i(loopbackrx_data), .src1_rdy_i(loopbackrx_src_rdy), .dst1_rdy_o(loopbackrx_dst_rdy), -      .data_o(testrx_data), .src_rdy_o(testrx_src_rdy), .dst_rdy_i(testrx_dst_rdy)); -    -   fifo36_mux rx_test_mux_lvl_2 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .data0_i(testrx_data), .src0_rdy_i(testrx_src_rdy), .dst0_rdy_o(testrx_dst_rdy), -      .data1_i(rx_data_i), .src1_rdy_i(rx_src_rdy_i), .dst1_rdy_o(rx_dst_rdy_o), -      .data_o(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy)); -    -   fifo_short #(.WIDTH(36)) loopback_fifo -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx | clear_rx), -      .datain(loopbacktx_data), .src_rdy_i(loopbacktx_src_rdy), .dst_rdy_o(loopbacktx_dst_rdy), -      .dataout(loopbackrx_data), .src_rdy_o(loopbackrx_src_rdy), .dst_rdy_i(loopbackrx_dst_rdy)); -    -   // Crossbar used as a demux for switching TX stream to main DSP or to test logic -   crossbar36 tx_crossbar_lvl_1 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .cross(sel_testtx), -      .data0_i(tx_data), .src0_rdy_i(tx_src_rdy), .dst0_rdy_o(tx_dst_rdy), -      .data1_i(tx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(),  // No 2nd input -      .data0_o(tx_data_o), .src0_rdy_o(tx_src_rdy_o), .dst0_rdy_i(tx_dst_rdy_i), -      .data1_o(testtx_data), .src1_rdy_o(testtx_src_rdy), .dst1_rdy_i(testtx_dst_rdy) ); -    -   crossbar36 tx_crossbar_lvl_2 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .cross(sel_loopbacktx), -      .data0_i(testtx_data), .src0_rdy_i(testtx_src_rdy), .dst0_rdy_o(testtx_dst_rdy), -      .data1_i(testtx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(),  // No 2nd input -      .data0_o(timedtx_data), .src0_rdy_o(timedtx_src_rdy), .dst0_rdy_i(timedtx_dst_rdy), -      .data1_o(loopbacktx_data), .src1_rdy_o(loopbacktx_src_rdy), .dst1_rdy_i(loopbacktx_dst_rdy) ); -    -   // Fixed rate TX traffic consumer -   fifo_pacer tx_pacer -     (.clk(fifo_clk), .reset(fifo_rst), .rate(test_rate), .enable(pkt_sink_enable), -      .src1_rdy_i(timedtx_src_rdy), .dst1_rdy_o(timedtx_dst_rdy), -      .src2_rdy_o(timedtx_src_rdy_int), .dst2_rdy_i(timedtx_dst_rdy_int), -      .underrun(tx_underrun), .overrun()); - -   packet_verifier32 pktver32 -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx), -      .data_i(timedtx_data), .src_rdy_i(timedtx_src_rdy_int), .dst_rdy_o(timedtx_dst_rdy_int), -      .total(total), .crc_err(crc_err), .seq_err(seq_err), .len_err(len_err)); - -   // Fixed rate RX traffic generator -   vita_pkt_gen pktgen -     (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx), -      .len(test_len), -      .data_o(timedrx_data), .src_rdy_o(timedrx_src_rdy_int), .dst_rdy_i(timedrx_dst_rdy_int)); - -   fifo_pacer rx_pacer -     (.clk(fifo_clk), .reset(fifo_rst), .rate(test_rate), .enable(pkt_src_enable), -      .src1_rdy_i(timedrx_src_rdy_int), .dst1_rdy_o(timedrx_dst_rdy_int), -      .src2_rdy_o(timedrx_src_rdy), .dst2_rdy_i(timedrx_dst_rdy), -      .underrun(), .overrun(rx_overrun)); -     // ////////////////////////////////////////////     //    DEBUG diff --git a/fpga/usrp2/gpif/lint b/fpga/usrp2/gpif/lint new file mode 100755 index 000000000..4316c89a9 --- /dev/null +++ b/fpga/usrp2/gpif/lint @@ -0,0 +1,2 @@ +iverilog -Wall -y . -y ../fifo/ -y ../control_lib/ -y ../models/ -y ../coregen/ -y ../simple_gemac/ -y ../sdr_lib/ -y ../vrt/ gpif.v 2>&1 | grep -v coregen | grep -v models + diff --git a/fpga/usrp2/sdr_lib/Makefile.srcs b/fpga/usrp2/sdr_lib/Makefile.srcs index defbced17..629b92cc8 100644 --- a/fpga/usrp2/sdr_lib/Makefile.srcs +++ b/fpga/usrp2/sdr_lib/Makefile.srcs @@ -25,8 +25,11 @@ cordic_z24.v \  cordic_stage.v \  dsp_core_rx.v \  dsp_core_tx.v \ +dspengine_16to8.v \  hb_dec.v \  hb_interp.v \ +pipectrl.v \ +pipestage.v \  round.v \  round_reg.v \  round_sd.v \ diff --git a/fpga/usrp2/sdr_lib/clip_reg.v b/fpga/usrp2/sdr_lib/clip_reg.v index d5e98d982..9098fd5b8 100644 --- a/fpga/usrp2/sdr_lib/clip_reg.v +++ b/fpga/usrp2/sdr_lib/clip_reg.v @@ -23,16 +23,24 @@  module clip_reg    #(parameter bits_in=0, -    parameter bits_out=0) +    parameter bits_out=0, +    parameter STROBED=1'b0)      (input clk,       input [bits_in-1:0] in, -     output reg [bits_out-1:0] out); +     output reg [bits_out-1:0] out, +     input strobe_in, +     output reg strobe_out);     wire [bits_out-1:0] temp;     clip #(.bits_in(bits_in),.bits_out(bits_out)) clip (.in(in),.out(temp)); + +   always @(posedge clk) +     strobe_out <= strobe_in; +        always @(posedge clk) -     out <= temp; +     if(strobe_in | ~STROBED) +       out <= temp;  endmodule // clip_reg diff --git a/fpga/usrp2/sdr_lib/dsp_core_rx.v b/fpga/usrp2/sdr_lib/dsp_core_rx.v index 639744de7..d1c7e238a 100644 --- a/fpga/usrp2/sdr_lib/dsp_core_rx.v +++ b/fpga/usrp2/sdr_lib/dsp_core_rx.v @@ -94,8 +94,10 @@ module dsp_core_rx  	    .xi({adc_i_mux[23],adc_i_mux}),. yi({adc_q_mux[23],adc_q_mux}), .zi(phase[31:8]),  	    .xo(i_cordic),.yo(q_cordic),.zo() ); -   clip_reg #(.bits_in(25), .bits_out(24)) clip_i (.clk(clk), .in(i_cordic), .out(i_cordic_clip)); -   clip_reg #(.bits_in(25), .bits_out(24)) clip_q (.clk(clk), .in(q_cordic), .out(q_cordic_clip)); +   clip_reg #(.bits_in(25), .bits_out(24)) clip_i +     (.clk(clk), .in(i_cordic), .strobe_in(1'b1), .out(i_cordic_clip)); +   clip_reg #(.bits_in(25), .bits_out(24)) clip_q +     (.clk(clk), .in(q_cordic), .strobe_in(1'b1), .out(q_cordic_clip));     // CIC decimator  24 bit I/O     cic_strober cic_strober(.clock(clk),.reset(rst),.enable(run),.rate(cic_decim_rate), diff --git a/fpga/usrp2/sdr_lib/dspengine_16to8.v b/fpga/usrp2/sdr_lib/dspengine_16to8.v new file mode 100644 index 000000000..53c5d29da --- /dev/null +++ b/fpga/usrp2/sdr_lib/dspengine_16to8.v @@ -0,0 +1,221 @@ + +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +module dspengine_16to8 +  #(parameter BASE = 0, +    parameter BUF_SIZE = 9) +   (input clk, input reset, input clear, +    input set_stb, input [7:0] set_addr, input [31:0] set_data, + +    output access_we, +    output access_stb, +    input access_ok, +    output access_done, +    output access_skip_read, +    output [BUF_SIZE-1:0] access_adr, +    input [BUF_SIZE-1:0] access_len, +    output [35:0] access_dat_o, +    input [35:0] access_dat_i +    ); + +   wire 	 convert; +   wire [17:0] 	 scale_factor; +    +   setting_reg #(.my_addr(BASE),.width(19)) sr_16to8 +     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), +      .in(set_data),.out({convert,scale_factor}),.changed()); +    +   reg [2:0] 	 dsp_state; +   localparam DSP_IDLE = 0; +   localparam DSP_PARSE_HEADER = 1; +   localparam DSP_CONVERT = 2; +   localparam DSP_CONVERT_DRAIN_PIPE = 3; +   localparam DSP_READ_TRAILER = 4; +   localparam DSP_WRITE_TRAILER = 5; +   localparam DSP_WRITE_HEADER = 6; +   localparam DSP_DONE = 7; + +   // Parse VITA header +   wire 	 is_if_data = (access_dat_i[31:29] == 3'b000); +   wire 	 has_streamid = access_dat_i[28]; +   wire 	 has_classid = access_dat_i[27]; +   wire 	 has_trailer = access_dat_i[26]; +   // 25:24 reserved, aka SOB/EOB +   wire 	 has_secs = |access_dat_i[23:22]; +   wire 	 has_tics = |access_dat_i[21:20]; +   wire [3:0] 	 hdr_length = 1 + has_streamid + has_classid + has_classid + has_secs + has_tics + has_tics; +    +   wire [35:0] 	 prod_i, prod_q; +   wire [15:0] 	 scaled_i, scaled_q; +   wire [7:0] 	 i8, q8; +   reg [7:0] 	 i8_reg, q8_reg; +   wire 	 stb_read, stb_mult, stb_clip, stb_round, val_read, val_mult, val_clip, val_round; +   wire 	 stb_out, stb_reg; +   reg 		 even; +    +   reg [BUF_SIZE-1:0] read_adr, write_adr; +   reg 		      has_trailer_reg; +    +   wire 	      last = (read_adr + 1) == (access_len - has_trailer_reg); +   wire 	      last_o, even_o; + +   wire 	      stb_write = stb_out & (even_o | last_o); +   wire 	      send_to_pipe = ~stb_write & (dsp_state == DSP_CONVERT); +   reg [31:0] 	      new_header, new_trailer, trailer_mask; +   reg [15:0] 	      length; +   reg 		      wait_for_trailer; +    +   always @(posedge clk) +     if(reset | clear) +       dsp_state <= DSP_IDLE; +     else +       case(dsp_state) +	 DSP_IDLE : +	   begin +	      read_adr <= 0; +	      write_adr <= 0; +	      even <= 0; +	      if(access_ok) +		dsp_state <= DSP_PARSE_HEADER; +	   end +	  +	 DSP_PARSE_HEADER : +	   begin +	      has_trailer_reg <= has_trailer; +	      new_header[31:16] <= access_dat_i[31:16]; +	      new_header[15:0] <= access_len; +	      length <= access_len; +	      if(is_if_data & convert) +		begin +		   read_adr <= hdr_length; +		   write_adr <= hdr_length; +		   dsp_state <= DSP_CONVERT; +		end +	      else +		dsp_state <= DSP_WRITE_HEADER; +	   end +	  +	 DSP_CONVERT: +	   begin +	      new_header[26] <= 1'b1;  // all converted packets have a trailer +	      if(stb_write) +		write_adr <= write_adr + 1; +	      else if(stb_read)   // should always be 1 if we are here +		begin +		   read_adr <= read_adr + 1; +		   even <= ~even; +		   if(last) +		     begin +			dsp_state <= DSP_CONVERT_DRAIN_PIPE; +			if(~even) +			  trailer_mask <= 32'h00400400; +			else +			  trailer_mask <= 32'h00400000; +		     end +		end +	   end +	  +	 DSP_CONVERT_DRAIN_PIPE : +	   if(stb_write) +	     begin +		write_adr <= write_adr + 1; +		if(last_o) +		  if(has_trailer_reg) +		    begin +		       dsp_state <= DSP_READ_TRAILER; +		       wait_for_trailer <= 0; +		    end +		  else +		    begin +		       dsp_state <= DSP_WRITE_TRAILER; +		       new_trailer <= trailer_mask; +		    end +	     end + +	 DSP_READ_TRAILER : +	   begin +	      wait_for_trailer <= 1; +	      if(wait_for_trailer) +		dsp_state <= DSP_WRITE_TRAILER; +	      new_trailer <= access_dat_i[31:0] | trailer_mask; +	   end + +	 DSP_WRITE_TRAILER : +	   begin +	      dsp_state <= DSP_WRITE_HEADER; +	      write_adr <= 0; +	      new_header[15:0] <= write_adr + 1; +	   end + +	 DSP_WRITE_HEADER : +	   dsp_state <= DSP_DONE; + +	 DSP_DONE : +	   begin +	      read_adr <= 0; +	      write_adr <= 0; +	      dsp_state <= DSP_IDLE; +	   end +       endcase // case (dsp_state) + +   assign access_skip_read = 0; +   assign access_done = (dsp_state == DSP_DONE); + +   assign access_stb = 1; + +   assign access_we = (dsp_state == DSP_WRITE_HEADER) |  +		      (dsp_state == DSP_WRITE_TRAILER) | +		      stb_write; + +   assign access_dat_o = (dsp_state == DSP_WRITE_HEADER) ? { 4'h1, new_header } : +			 (dsp_state == DSP_WRITE_TRAILER) ? { 4'h2, new_trailer } : +			 (last_o&~even_o) ? {4'h0, 16'd0, i8, q8 } :  +			 {4'h0, i8, q8, i8_reg, q8_reg }; +    +   assign access_adr = (stb_write|(dsp_state == DSP_WRITE_HEADER)|(dsp_state == DSP_WRITE_TRAILER)) ? write_adr : read_adr; +       +   // DSP Pipeline +    +   wire [15:0] i16 = access_dat_i[31:16]; +   wire [15:0] q16 = access_dat_i[15:0]; + +   pipectrl #(.STAGES(4), .TAGWIDTH(2)) pipectrl  +     (.clk(clk), .reset(reset), +      .src_rdy_i(send_to_pipe), .dst_rdy_o(), // dst_rdy_o will always be 1 since dst_rdy_i is 1, below +      .src_rdy_o(stb_out), .dst_rdy_i(1),   // always accept output of chain +      .strobes({stb_round,stb_clip,stb_mult,stb_read}), .valids({val_round,val_clip,val_mult,val_read}), +      .tag_i({last,even}), .tag_o({last_o,even_o})); + +   always @(posedge clk) +     if(stb_out & ~even_o) +       {i8_reg,q8_reg} <= {i8,q8}; +    +   MULT18X18S mult_i  +     (.P(prod_i), .A(scale_factor), .B({i16,2'b00}), .C(clk), .CE(stb_mult), .R(reset) );  +   clip_reg #(.bits_in(24),.bits_out(16),.STROBED(1)) clip_i  +     (.clk(clk), .in(prod_i[35:12]), .out(scaled_i), .strobe_in(stb_clip), .strobe_out()); +   round_sd #(.WIDTH_IN(16),.WIDTH_OUT(8),.DISABLE_SD(1)) round_i +     (.clk(clk), .reset(reset), .in(scaled_i), .strobe_in(stb_round), .out(i8), .strobe_out()); + +   MULT18X18S mult_q  +     (.P(prod_q), .A(scale_factor), .B({q16,2'b00}), .C(clk), .CE(stb_mult), .R(reset) );  +   clip_reg #(.bits_in(24),.bits_out(16),.STROBED(1)) clip_q  +     (.clk(clk), .in(prod_q[35:12]), .out(scaled_q), .strobe_in(stb_clip), .strobe_out()); +   round_sd #(.WIDTH_IN(16),.WIDTH_OUT(8),.DISABLE_SD(1)) round_q +     (.clk(clk), .reset(reset), .in(scaled_q), .strobe_in(stb_round), .out(q8), .strobe_out()); + +endmodule // dspengine_16to8 diff --git a/fpga/usrp2/sdr_lib/pipectrl.v b/fpga/usrp2/sdr_lib/pipectrl.v new file mode 100644 index 000000000..85d0ce04f --- /dev/null +++ b/fpga/usrp2/sdr_lib/pipectrl.v @@ -0,0 +1,66 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +// Control DSP pipeline with 1 cycle per stage.  Minimum 2 stages or this won't work +module pipectrl +  #(parameter STAGES = 2,  +    parameter TAGWIDTH = 1) +   (input clk, +    input reset, +    input src_rdy_i, +    output dst_rdy_o, +    output src_rdy_o, +    input dst_rdy_i, +    output [STAGES-1:0] strobes, +    output [STAGES-1:0] valids, +    input [TAGWIDTH-1:0] tag_i, +    output [TAGWIDTH-1:0] tag_o); + +   wire 		new_input = src_rdy_i & dst_rdy_o; +   wire 		new_output = src_rdy_o & dst_rdy_i; +   wire [TAGWIDTH-1:0] 	tags [STAGES-1:0]; + +   assign dst_rdy_o = ~valids[0] | strobes[1]; + +   pipestage #(.TAGWIDTH(TAGWIDTH)) head +     (.clk(clk),.reset(reset), .stb_in(strobes[0]), .stb_out(strobes[1]),.valid(valids[0]), +      .tag_in(tag_i), .tag_out(tags[0])); +   assign strobes[0] = src_rdy_i & (~valids[0] | strobes[1]); + +   genvar 		i; +   generate +      for(i = 1; i < STAGES - 1; i = i + 1) +	begin : gen_stages +	   pipestage #(.TAGWIDTH(TAGWIDTH)) pipestage +	     (.clk(clk),.reset(reset), .stb_in(strobes[i]),.stb_out(strobes[i+1]),.valid(valids[i]), +	      .tag_in(tags[i-1]),.tag_out(tags[i])); +	   assign strobes[i] = valids[i-1] & (~valids[i] | strobes[i+1]); +	end +   endgenerate + +   pipestage #(.TAGWIDTH(TAGWIDTH)) tail +     (.clk(clk),.reset(reset), .stb_in(strobes[STAGES-1]), .stb_out(dst_rdy_i),.valid(valids[STAGES-1]), +      .tag_in(tags[STAGES-2]), .tag_out(tags[STAGES-1])); +   assign strobes[STAGES-1] = valids[STAGES-2] & (~valids[STAGES-1] | new_output); +    +   assign src_rdy_o = valids[STAGES-1]; + +   assign tag_o = tags[STAGES-1]; +    +endmodule // pipectrl + + diff --git a/fpga/usrp2/sdr_lib/pipestage.v b/fpga/usrp2/sdr_lib/pipestage.v new file mode 100644 index 000000000..011afb1ba --- /dev/null +++ b/fpga/usrp2/sdr_lib/pipestage.v @@ -0,0 +1,45 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +module pipestage +  #(parameter TAGWIDTH = 1) +   (input clk, +    input reset, +    input stb_in, +    input stb_out, +    output reg valid, +    input [TAGWIDTH-1:0] tag_in, +    output reg [TAGWIDTH-1:0] tag_out); + +   always @(posedge clk) +     if(reset) +       begin +	  valid <= 0; +	  tag_out <= 0; +       end +     else if(stb_in) +       begin +	  valid <= 1; +	  tag_out <= tag_in; +       end +     else if(stb_out) +       begin +	  valid <= 0; +	  tag_out <= 0; +       end +    +endmodule // pipestage diff --git a/fpga/usrp2/sdr_lib/round.v b/fpga/usrp2/sdr_lib/round.v index 7a137d702..26d5a4cf4 100644 --- a/fpga/usrp2/sdr_lib/round.v +++ b/fpga/usrp2/sdr_lib/round.v @@ -2,7 +2,7 @@  //  //  USRP - Universal Software Radio Peripheral  // -//  Copyright (C) 2007 Matt Ettus +//  Copyright (C) 2011 Matt Ettus  //  //  This program is free software; you can redistribute it and/or modify  //  it under the terms of the GNU General Public License as published by @@ -24,12 +24,36 @@  module round    #(parameter bits_in=0, -    parameter bits_out=0) +    parameter bits_out=0, +    parameter round_to_zero=0,       // original behavior +    parameter round_to_nearest=1,    // lowest noise +    parameter trunc=0)               // round to negative infinity      (input [bits_in-1:0] in,       output [bits_out-1:0] out,       output [bits_in-bits_out:0] err); -   assign out = in[bits_in-1:bits_in-bits_out] + (in[bits_in-1] & |in[bits_in-bits_out-1:0]); +   wire 			 round_corr,round_corr_trunc,round_corr_rtz,round_corr_nearest,round_corr_nearest_safe; +    +   assign 			 round_corr_trunc = 0; +   assign 			 round_corr_rtz = (in[bits_in-1] & |in[bits_in-bits_out-1:0]); +   assign 			 round_corr_nearest = in[bits_in-bits_out-1]; + +   generate +      if(bits_in-bits_out > 1) +	assign 			 round_corr_nearest_safe = (~in[bits_in-1] & (&in[bits_in-2:bits_out])) ? 0 : +				 round_corr_nearest; +      else +	assign round_corr_nearest_safe = round_corr_nearest; +   endgenerate +    +       +   assign round_corr = round_to_nearest ? round_corr_nearest_safe : +		       trunc ? round_corr_trunc :  +		       round_to_zero ? round_corr_rtz : +		       0;  // default to trunc +       +   assign out = in[bits_in-1:bits_in-bits_out] + round_corr; +        assign err = in - {out,{(bits_in-bits_out){1'b0}}};  endmodule // round diff --git a/fpga/usrp2/sdr_lib/round_sd.v b/fpga/usrp2/sdr_lib/round_sd.v index aeeb3502f..94584f6ef 100644 --- a/fpga/usrp2/sdr_lib/round_sd.v +++ b/fpga/usrp2/sdr_lib/round_sd.v @@ -2,7 +2,8 @@  module round_sd    #(parameter WIDTH_IN=18, -    parameter WIDTH_OUT=16) +    parameter WIDTH_OUT=16, +    parameter DISABLE_SD=0)     (input clk, input reset,      input [WIDTH_IN-1:0] in, input strobe_in,      output [WIDTH_OUT-1:0] out, output strobe_out); @@ -15,7 +16,7 @@ module round_sd     sign_extend #(.bits_in(ERR_WIDTH),.bits_out(WIDTH_IN)) ext_err (.in(err), .out(err_ext));     add2_and_clip_reg #(.WIDTH(WIDTH_IN)) add2_and_clip_reg -     (.clk(clk), .rst(reset), .in1(in), .in2(err_ext), .strobe_in(strobe_in), .sum(sum), .strobe_out(strobe_out)); +     (.clk(clk), .rst(reset), .in1(in), .in2((DISABLE_SD == 0) ? err_ext : 0), .strobe_in(strobe_in), .sum(sum), .strobe_out(strobe_out));     round #(.bits_in(WIDTH_IN),.bits_out(WIDTH_OUT)) round_sum (.in(sum), .out(out), .err(err)); diff --git a/fpga/usrp2/sdr_lib/round_tb.v b/fpga/usrp2/sdr_lib/round_tb.v new file mode 100644 index 000000000..ddc464f4a --- /dev/null +++ b/fpga/usrp2/sdr_lib/round_tb.v @@ -0,0 +1,61 @@ +// -*- verilog -*- +// +//  USRP - Universal Software Radio Peripheral +// +//  Copyright (C) 2011 Matt Ettus +// +//  This program is free software; you can redistribute it and/or modify +//  it under the terms of the GNU General Public License as published by +//  the Free Software Foundation; either version 2 of the License, or +//  (at your option) any later version. +// +//  This program 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 General Public License for more details. +// +//  You should have received a copy of the GNU General Public License +//  along with this program; if not, write to the Free Software +//  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA +// + +// Rounding "macro" +// Keeps the topmost bits, does proper 2s comp round to zero (unbiased truncation) + +module round_tb(); + +   localparam IW=8; +   localparam OW=4; +   localparam EW=IW-OW+1; +    +   reg signed [IW-1:0] in; +   wire signed [OW-1:0] out; +   wire signed [EW-1:0] err; + +   round #(.bits_in(IW), +	   .bits_out(OW), +	   .round_to_zero(0),       // original behavior +	   .round_to_nearest(1),    // lowest noise +	   .trunc(0))               // round to negative infinity +   round (.in(in),.out(out),.err(err)); + +   initial $dumpfile("round_tb.vcd"); +   initial $dumpvars(0,round_tb); + +   wire signed [IW-1:0] out_round = {out,{IW-OW{1'b0}}}; +    +   initial +     begin +	in <= -129; +	#1; +	repeat (260) +	  begin +	     in <= in + 1; +	     #1; +	     $display("In %d, out %d, out_rnd %d, err %d, real err %d",in,out,out_round,-err,out_round-in); +	     #1; +	  end +	$finish; +     end +      +endmodule // round diff --git a/fpga/usrp2/sdr_lib/rx_dcoffset.v b/fpga/usrp2/sdr_lib/rx_dcoffset.v index 9840e9e1f..04d7795c0 100644 --- a/fpga/usrp2/sdr_lib/rx_dcoffset.v +++ b/fpga/usrp2/sdr_lib/rx_dcoffset.v @@ -42,8 +42,9 @@ module rx_dcoffset         end       else if(set_now)         begin -	  //integrator <= {set_data[30:0],{(31-int_width){1'b0}}};  	  fixed <= set_data[31]; +	  if(set_data[30]) +	    integrator <= {set_data[29:0],{(int_width-30){1'b0}}};         end       else if(~fixed)         integrator <= integrator +  {{(alpha_shift){out[WIDTH-1]}},out}; diff --git a/fpga/usrp2/sdr_lib/small_hb_int.v b/fpga/usrp2/sdr_lib/small_hb_int.v index 387f9e1cb..b69c45413 100644 --- a/fpga/usrp2/sdr_lib/small_hb_int.v +++ b/fpga/usrp2/sdr_lib/small_hb_int.v @@ -73,8 +73,8 @@ module small_hb_int       final_round (.clk(clk),.in(accum),.out(accum_rnd));     wire [WIDTH-1:0] 	 clipped; -   clip_reg #(.bits_in(WIDTH+3),.bits_out(WIDTH)) -     final_clip (.clk(clk),.in(accum_rnd),.out(clipped)); +   clip_reg #(.bits_in(WIDTH+3),.bits_out(WIDTH)) final_clip +     (.clk(clk),.in(accum_rnd),.strobe_in(1'b1), .out(clipped));     reg [WIDTH-1:0] 	 saved, saved_d3;     always @(posedge clk) diff --git a/fpga/usrp2/top/B100/Makefile b/fpga/usrp2/top/B100/Makefile new file mode 100644 index 000000000..3ddef1024 --- /dev/null +++ b/fpga/usrp2/top/B100/Makefile @@ -0,0 +1,14 @@ +# +# Copyright 2011 Ettus Research LLC +# + +all: B100 +	find -name "*.twr" | xargs grep constraint | grep met + +clean: +	rm -rf build* + +B100: +	make -f Makefile.$@ bin + +.PHONY: all clean diff --git a/fpga/usrp2/top/B100/u1plus_core.v b/fpga/usrp2/top/B100/u1plus_core.v index e11a4c37e..86bf747a0 100644 --- a/fpga/usrp2/top/B100/u1plus_core.v +++ b/fpga/usrp2/top/B100/u1plus_core.v @@ -56,17 +56,14 @@ module u1plus_core     localparam SR_CLEAR_TX_FIFO = 62; // 1 reg     localparam SR_GLOBAL_RESET = 63;  // 1 reg -   wire [7:0]	COMPAT_NUM = 8'd5; +   localparam SR_GPIO = 128;         // 5 regs     wire 	wb_clk = clk_fpga;     wire 	wb_rst, global_reset;     wire 	pps_int;     wire [63:0] 	vita_time, vita_time_pps; -   reg [15:0] 	reg_leds, reg_cgen_ctrl, reg_test; -   wire [15:0] 	xfer_rate = 0; -   wire [7:0] 	test_rate; -   wire [3:0] 	test_ctrl; +   reg [15:0] 	reg_cgen_ctrl, reg_test;     wire [7:0] 	set_addr;     wire [31:0] 	set_data; @@ -90,7 +87,6 @@ module u1plus_core     reset_sync reset_sync_wb(.clk(wb_clk), .reset_in(rst_fpga | global_reset), .reset_out(wb_rst));     reset_sync reset_sync_gp(.clk(gpif_clk), .reset_in(rst_fpga | global_reset), .reset_out(gpif_rst)); -   wire [15:0] 	test_len;     // /////////////////////////////////////////////////////////////////////////////////////     // GPIF Slave to Wishbone Master @@ -135,7 +131,7 @@ module u1plus_core  	 .tx_underrun(tx_underrun_gpif), .rx_overrun(rx_overrun_gpif), -	 .frames_per_packet(frames_per_packet), .test_len(test_len), .test_rate(test_rate), .test_ctrl(test_ctrl), +	 .frames_per_packet(frames_per_packet),  	 .debug0(debug0), .debug1(debug1));     // ///////////////////////////////////////////////////////////////////////// @@ -166,7 +162,7 @@ module u1plus_core        .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0),        .debug() ); -   vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain0 +   vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain0       (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),        .vita_time(vita_time), .overrun(rx_overrun_dsp0), @@ -189,7 +185,7 @@ module u1plus_core        .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1),        .debug() ); -   vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain1 +   vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain1       (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),        .vita_time(vita_time), .overrun(rx_overrun_dsp1), @@ -252,14 +248,20 @@ module u1plus_core     wire 	 s8_we,s9_we,sa_we,sb_we,sc_we,sd_we, se_we, sf_we;     wb_1master #(.dw(dw), .aw(aw), .sw(sw), .decode_w(4), -		.s0_addr(4'h0), .s0_mask(4'hF), .s1_addr(4'h1), .s1_mask(4'hF), -		.s2_addr(4'h2), .s2_mask(4'hF),	.s3_addr(4'h3), .s3_mask(4'hF), -		.s4_addr(4'h4), .s4_mask(4'hF),	.s5_addr(4'h5), .s5_mask(4'hF), -		.s6_addr(4'h6), .s6_mask(4'hF),	.s7_addr(4'h7), .s7_mask(4'hF), -		.s8_addr(4'h8), .s8_mask(4'hE),	.s9_addr(4'hf), .s9_mask(4'hF), // slave 8 is double wide -		.sa_addr(4'ha), .sa_mask(4'hF),	.sb_addr(4'hb), .sb_mask(4'hF), -		.sc_addr(4'hc), .sc_mask(4'hF),	.sd_addr(4'hd), .sd_mask(4'hF), -		.se_addr(4'he), .se_mask(4'hF),	.sf_addr(4'hf), .sf_mask(4'hF)) +		.s0_addr(4'h0), .s0_mask(4'hF), // Misc Regs +		.s1_addr(4'h1), .s1_mask(4'hF), // Unused +		.s2_addr(4'h2), .s2_mask(4'hF),	// SPI +		.s3_addr(4'h3), .s3_mask(4'hF), // I2C +		.s4_addr(4'h4), .s4_mask(4'hF),	// Unused +		.s5_addr(4'h5), .s5_mask(4'hF), // Unused on B1x0, Async Msg on E1x0 +		.s6_addr(4'h6), .s6_mask(4'hF),	// Unused +		.s7_addr(4'h7), .s7_mask(4'hF), // Readback MUX +		.s8_addr(4'h8), .s8_mask(4'h8), // Setting Regs -- slave 8 is 8 slaves wide +		// slaves 9-f alias to slave 1, all are unused +		.s9_addr(4'h1), .s9_mask(4'hF), +		.sa_addr(4'h1), .sa_mask(4'hF),	.sb_addr(4'h1), .sb_mask(4'hF), +		.sc_addr(4'h1), .sc_mask(4'hF),	.sd_addr(4'h1), .sd_mask(4'hF), +		.se_addr(4'h1), .se_mask(4'hF),	.sf_addr(4'h1), .sf_mask(4'hF))     wb_1master       (.clk_i(wb_clk),.rst_i(wb_rst),               .m0_dat_o(m0_dat_miso),.m0_ack_o(m0_ack),.m0_err_o(m0_err),.m0_rty_o(m0_rty),.m0_dat_i(m0_dat_mosi), @@ -297,76 +299,48 @@ module u1plus_core        .sf_dat_o(sf_dat_mosi),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),        .sf_dat_i(sf_dat_miso),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0) ); -   assign s5_ack = 0;    +   assign s1_ack = 0;   assign s4_ack = 0;   assign s5_ack = 0;   assign s6_ack = 0;     assign s9_ack = 0;   assign sa_ack = 0;   assign sb_ack = 0;     assign sc_ack = 0;   assign sd_ack = 0;   assign se_ack = 0;   assign sf_ack = 0;     // /////////////////////////////////////////////////////////////////////////////////////     // Slave 0, Misc LEDs, Switches, controls -   localparam REG_LEDS = 7'd0;         // out     localparam REG_CGEN_CTRL = 7'd4;    // out     localparam REG_CGEN_ST = 7'd6;      // in     localparam REG_TEST = 7'd8;         // out     localparam REG_RX_FRAMELEN = 7'd10; // in     localparam REG_TX_FRAMELEN = 7'd12; // out -   localparam REG_XFER_RATE = 7'd14;   // out -   localparam REG_COMPAT = 7'd16;      // in     always @(posedge wb_clk)       if(wb_rst)         begin -	  reg_leds <= 0;  	  reg_cgen_ctrl <= 2'b11;  	  reg_test <= 0; -	  //xfer_rate <= 0;  	  frames_per_packet <= 0;         end       else         if(s0_cyc & s0_stb & s0_we)   	 case(s0_adr[6:0]) -	   REG_LEDS : -	     reg_leds <= s0_dat_mosi;  	   REG_CGEN_CTRL :  	     reg_cgen_ctrl <= s0_dat_mosi;  	   REG_TEST :  	     reg_test <= s0_dat_mosi;  	   REG_RX_FRAMELEN :  	     frames_per_packet <= s0_dat_mosi[7:0]; -	   //REG_XFER_RATE : -	     //xfer_rate <= s0_dat_mosi;  	 endcase // case (s0_adr[6:0]) -   assign test_ctrl = xfer_rate[11:8]; -   assign test_rate = xfer_rate[7:0]; -   assign test_len = reg_test[15:0]; -        assign debug_led = {run_tx, (run_rx0 | run_rx1), cgen_st_ld};     assign { cgen_sync_b, cgen_ref_sel } = reg_cgen_ctrl; -   assign s0_dat_miso = (s0_adr[6:0] == REG_LEDS) ? reg_leds :  -			(s0_adr[6:0] == REG_CGEN_CTRL) ? reg_cgen_ctrl : +   assign s0_dat_miso = (s0_adr[6:0] == REG_CGEN_CTRL) ? reg_cgen_ctrl :  			(s0_adr[6:0] == REG_CGEN_ST) ? {13'b0,cgen_st_status,cgen_st_ld,cgen_st_refmon} :  			(s0_adr[6:0] == REG_TEST) ? reg_test : -			(s0_adr[6:0] == REG_COMPAT) ? { 8'd0, COMPAT_NUM } :  			16'hBEEF;     assign s0_ack = s0_stb & s0_cyc;     // ///////////////////////////////////////////////////////////////////////////////////// -   // Slave 1, UART -   //    depth of 3 is 128 entries, clkdiv of 278 gives 230.4k with a 64 MHz system clock - -/*    -   simple_uart #(.TXDEPTH(3),.RXDEPTH(3), .CLKDIV_DEFAULT(278)) uart  -     (.clk_i(wb_clk),.rst_i(wb_rst), -      .we_i(s1_we),.stb_i(s1_stb),.cyc_i(s1_cyc),.ack_o(s1_ack), -      .adr_i(s1_adr[3:1]),.dat_i({16'd0,s1_dat_mosi}),.dat_o(s1_dat_miso), -      .rx_int_o(),.tx_int_o(), -      .tx_o(debug_txd),.rx_i(debug_rxd),.baud_o()); -*/ -    -   // /////////////////////////////////////////////////////////////////////////////////////     // Slave 2, SPI     spi_top16 shared_spi @@ -394,39 +368,31 @@ module u1plus_core     IOBUF sda_pin(.O(sda_pad_i), .IO(db_sda), .I(sda_pad_o), .T(sda_pad_oen_o));     // ///////////////////////////////////////////////////////////////////////// -   // GPIOs -- Slave #4 +   // GPIOs -   wire [31:0] 	atr_lines; -   wire [31:0] 	debug_gpio_0, debug_gpio_1; +   wire [31:0] gpio_readback; -   nsgpio16LE  -     nsgpio16LE(.clk_i(wb_clk),.rst_i(wb_rst), -		.cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[3:0]),.we_i(s4_we), -		.dat_i(s4_dat_mosi),.dat_o(s4_dat_miso),.ack_o(s4_ack), -		.atr(atr_lines),.debug_0(debug_gpio_0),.debug_1(debug_gpio_1), -		.gpio( {io_tx,io_rx} ) ); +   gpio_atr #(.BASE(SR_GPIO), .WIDTH(32))  +   gpio_atr(.clk(wb_clk),.reset(wb_rst), +	    .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +	    .rx(run_rx0 | run_rx1), .tx(run_tx), +	    .gpio({io_tx,io_rx}), .gpio_readback(gpio_readback) );     // /////////////////////////////////////////////////////////////////////////     // Settings Bus -- Slave #8 + 9     // only have 64 regs, 32 bits each with current setup... -   settings_bus_16LE #(.AWIDTH(11),.RWIDTH(6)) settings_bus_16LE +   settings_bus_16LE #(.AWIDTH(11),.RWIDTH(8)) settings_bus_16LE       (.wb_clk(wb_clk),.wb_rst(wb_rst),.wb_adr_i(s8_adr),.wb_dat_i(s8_dat_mosi),        .wb_stb_i(s8_stb),.wb_we_i(s8_we),.wb_ack_o(s8_ack),        .strobe(set_stb),.addr(set_addr),.data(set_data) );     // ///////////////////////////////////////////////////////////////////////// -   // ATR Controller -- Slave #6 - -   atr_controller16 atr_controller16 -     (.clk_i(wb_clk), .rst_i(wb_rst), -      .adr_i(s6_adr[5:0]), .sel_i(s6_sel), .dat_i(s6_dat_mosi), .dat_o(s6_dat_miso), -      .we_i(s6_we), .stb_i(s6_stb), .cyc_i(s6_cyc), .ack_o(s6_ack), -      .run_rx(run_rx0 | run_rx1), .run_tx(run_tx), .ctrl_lines(atr_lines)); - -   // /////////////////////////////////////////////////////////////////////////     // Readback mux 32 -- Slave #7 +   //compatibility number -> increment when the fpga has been sufficiently altered +   localparam compat_num = {16'd8, 16'd0}; //major, minor +     wire [31:0] reg_test32;     setting_reg #(.my_addr(SR_REG_TEST32)) sr_reg_test32 @@ -440,7 +406,7 @@ module u1plus_core        .word00(vita_time[63:32]),        .word01(vita_time[31:0]),        .word02(vita_time_pps[63:32]),    .word03(vita_time_pps[31:0]),        .word04(reg_test32),              .word05(32'b0), -      .word06(32'b0),                   .word07(32'b0), +      .word06(compat_num),              .word07(gpio_readback),        .word08(32'b0),                   .word09(32'b0),        .word10(32'b0),                   .word11(32'b0),        .word12(32'b0),                   .word13(32'b0), @@ -460,7 +426,5 @@ module u1plus_core     assign debug_clk = 2'b00; // { gpif_clk, clk_fpga };     assign debug = 0; -   assign debug_gpio_0 = 0; -   assign debug_gpio_1 = 0;  endmodule // u1plus_core diff --git a/fpga/usrp2/top/E1x0/Makefile b/fpga/usrp2/top/E1x0/Makefile new file mode 100644 index 000000000..0ca8ed2dd --- /dev/null +++ b/fpga/usrp2/top/E1x0/Makefile @@ -0,0 +1,17 @@ +# +# Copyright 2011 Ettus Research LLC +# + +all: E100 E110 +	find -name "*.twr" | xargs grep constraint | grep met + +clean: +	rm -rf build* + +E100: +	make -f Makefile.$@ bin + +E110: +	make -f Makefile.$@ bin + +.PHONY: all clean diff --git a/fpga/usrp2/top/E1x0/u1e_core.v b/fpga/usrp2/top/E1x0/u1e_core.v index adc3c5aab..496a7ef4c 100644 --- a/fpga/usrp2/top/E1x0/u1e_core.v +++ b/fpga/usrp2/top/E1x0/u1e_core.v @@ -60,14 +60,14 @@ module u1e_core     localparam SR_CLEAR_TX_FIFO = 62; // 1 reg     localparam SR_GLOBAL_RESET = 63;  // 1 reg -   wire [7:0]	COMPAT_NUM = 8'd6; +   localparam SR_GPIO = 128;         // 5 regs     wire 	wb_clk = clk_fpga;     wire 	wb_rst, global_reset;     wire 	pps_int;     wire [63:0] 	vita_time, vita_time_pps; -   reg [15:0] 	reg_leds, reg_cgen_ctrl, reg_test, xfer_rate; +   reg [15:0] 	reg_cgen_ctrl, reg_test, xfer_rate;     wire [7:0] 	test_rate;     wire [3:0] 	test_ctrl; @@ -167,7 +167,7 @@ module u1e_core        .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0),        .debug() ); -   vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain0 +   vita_rx_chain #(.BASE(SR_RX_CTRL0), .UNIT(0), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain0       (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),        .vita_time(vita_time), .overrun(rx_overrun_dsp0), @@ -190,7 +190,7 @@ module u1e_core        .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1),        .debug() ); -   vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain1 +   vita_rx_chain #(.BASE(SR_RX_CTRL1), .UNIT(1), .FIFOSIZE(10), .PROT_ENG_FLAGS(0)) vita_rx_chain1       (.clk(wb_clk),.reset(wb_rst),.clear(clear_rx),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),        .vita_time(vita_time), .overrun(rx_overrun_dsp1), @@ -253,14 +253,20 @@ module u1e_core     wire 	 s8_we,s9_we,sa_we,sb_we,sc_we,sd_we, se_we, sf_we;     wb_1master #(.dw(dw), .aw(aw), .sw(sw), .decode_w(4), -		.s0_addr(4'h0), .s0_mask(4'hF), .s1_addr(4'h1), .s1_mask(4'hF), -		.s2_addr(4'h2), .s2_mask(4'hF),	.s3_addr(4'h3), .s3_mask(4'hF), -		.s4_addr(4'h4), .s4_mask(4'hF),	.s5_addr(4'h5), .s5_mask(4'hF), -		.s6_addr(4'h6), .s6_mask(4'hF),	.s7_addr(4'h7), .s7_mask(4'hF), -		.s8_addr(4'h8), .s8_mask(4'hE),	.s9_addr(4'hf), .s9_mask(4'hF), // slave 8 is double wide -		.sa_addr(4'ha), .sa_mask(4'hF),	.sb_addr(4'hb), .sb_mask(4'hF), -		.sc_addr(4'hc), .sc_mask(4'hF),	.sd_addr(4'hd), .sd_mask(4'hF), -		.se_addr(4'he), .se_mask(4'hF),	.sf_addr(4'hf), .sf_mask(4'hF)) +		.s0_addr(4'h0), .s0_mask(4'hF), // Misc Regs +		.s1_addr(4'h1), .s1_mask(4'hF), // Unused +		.s2_addr(4'h2), .s2_mask(4'hF),	// SPI +		.s3_addr(4'h3), .s3_mask(4'hF), // I2C +		.s4_addr(4'h4), .s4_mask(4'hF),	// Unused +		.s5_addr(4'h5), .s5_mask(4'hF), // Unused on B1x0, Async Msg on E1x0 +		.s6_addr(4'h6), .s6_mask(4'hF),	// Unused +		.s7_addr(4'h7), .s7_mask(4'hF), // Readback MUX +		.s8_addr(4'h8), .s8_mask(4'h8), // Setting Regs -- slave 8 is 8 slaves wide +		// slaves 9-f alias to slave 1, all are unused +		.s9_addr(4'h1), .s9_mask(4'hF), +		.sa_addr(4'h1), .sa_mask(4'hF),	.sb_addr(4'h1), .sb_mask(4'hF), +		.sc_addr(4'h1), .sc_mask(4'hF),	.sd_addr(4'h1), .sd_mask(4'hF), +		.se_addr(4'h1), .se_mask(4'hF),	.sf_addr(4'h1), .sf_mask(4'hF))     wb_1master       (.clk_i(wb_clk),.rst_i(wb_rst),               .m0_dat_o(m0_dat_miso),.m0_ack_o(m0_ack),.m0_err_o(m0_err),.m0_rty_o(m0_rty),.m0_dat_i(m0_dat_mosi), @@ -298,23 +304,21 @@ module u1e_core        .sf_dat_o(sf_dat_mosi),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),        .sf_dat_i(sf_dat_miso),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0) ); +   assign s1_ack = 0;   assign s4_ack = 0;   assign s6_ack = 0;     assign s9_ack = 0;   assign sa_ack = 0;   assign sb_ack = 0;     assign sc_ack = 0;   assign sd_ack = 0;   assign se_ack = 0;   assign sf_ack = 0;     // /////////////////////////////////////////////////////////////////////////////////////     // Slave 0, Misc LEDs, Switches, controls -   localparam REG_LEDS = 7'd0;         // out     localparam REG_CGEN_CTRL = 7'd4;    // out     localparam REG_CGEN_ST = 7'd6;      // in     localparam REG_TEST = 7'd8;         // out     localparam REG_XFER_RATE = 7'd14;   // out -   localparam REG_COMPAT = 7'd16;      // in     always @(posedge wb_clk)       if(wb_rst)         begin -	  reg_leds <= 0;  	  reg_cgen_ctrl <= 2'b11;  	  reg_test <= 0;  	  xfer_rate <= 0; @@ -322,8 +326,6 @@ module u1e_core       else         if(s0_cyc & s0_stb & s0_we)   	 case(s0_adr[6:0]) -	   REG_LEDS : -	     reg_leds <= s0_dat_mosi;  	   REG_CGEN_CTRL :  	     reg_cgen_ctrl <= s0_dat_mosi;  	   REG_TEST : @@ -338,27 +340,14 @@ module u1e_core     assign { debug_led[3:0] } = ~{1'b1, run_tx, run_rx0 | run_rx1, cgen_st_ld};     assign { cgen_sync_b, cgen_ref_sel } = reg_cgen_ctrl; -   assign s0_dat_miso = (s0_adr[6:0] == REG_LEDS) ? reg_leds :  -			(s0_adr[6:0] == REG_CGEN_CTRL) ? reg_cgen_ctrl : +   assign s0_dat_miso = (s0_adr[6:0] == REG_CGEN_CTRL) ? reg_cgen_ctrl :  			(s0_adr[6:0] == REG_CGEN_ST) ? {13'b0,cgen_st_status,cgen_st_ld,cgen_st_refmon} :  			(s0_adr[6:0] == REG_TEST) ? reg_test : -			(s0_adr[6:0] == REG_COMPAT) ? { 8'd0, COMPAT_NUM } :  			16'hBEEF;     assign s0_ack = s0_stb & s0_cyc;     // ///////////////////////////////////////////////////////////////////////////////////// -   // Slave 1, UART -   //    depth of 3 is 128 entries, clkdiv of 278 gives 230.4k with a 64 MHz system clock -    -   simple_uart #(.TXDEPTH(3),.RXDEPTH(3), .CLKDIV_DEFAULT(278)) uart  -     (.clk_i(wb_clk),.rst_i(wb_rst), -      .we_i(s1_we),.stb_i(s1_stb),.cyc_i(s1_cyc),.ack_o(s1_ack), -      .adr_i(s1_adr[3:1]),.dat_i({16'd0,s1_dat_mosi}),.dat_o(s1_dat_miso), -      .rx_int_o(),.tx_int_o(), -      .tx_o(debug_txd),.rx_i(debug_rxd),.baud_o()); - -   // /////////////////////////////////////////////////////////////////////////////////////     // Slave 2, SPI     spi_top16 shared_spi @@ -386,17 +375,15 @@ module u1e_core     IOBUF sda_pin(.O(sda_pad_i), .IO(db_sda), .I(sda_pad_o), .T(sda_pad_oen_o));     // ///////////////////////////////////////////////////////////////////////// -   // GPIOs -- Slave #4 +   // GPIOs -   wire [31:0] 	atr_lines; -   wire [31:0] 	debug_gpio_0, debug_gpio_1; +   wire [31:0] gpio_readback; -   nsgpio16LE  -     nsgpio16LE(.clk_i(wb_clk),.rst_i(wb_rst), -		.cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[3:0]),.we_i(s4_we), -		.dat_i(s4_dat_mosi),.dat_o(s4_dat_miso),.ack_o(s4_ack), -		.atr(atr_lines),.debug_0(debug_gpio_0),.debug_1(debug_gpio_1), -		.gpio( {io_tx,io_rx} ) ); +   gpio_atr #(.BASE(SR_GPIO), .WIDTH(32))  +   gpio_atr(.clk(wb_clk),.reset(wb_rst), +	    .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +	    .rx(run_rx0 | run_rx1), .tx(run_tx), +	    .gpio({io_tx,io_rx}), .gpio_readback(gpio_readback) );     ////////////////////////////////////////////////////////////////////////////     // FIFO to WB slave for async messages - Slave #5 @@ -440,23 +427,17 @@ module u1e_core     // Settings Bus -- Slave #8 + 9     // only have 64 regs, 32 bits each with current setup... -   settings_bus_16LE #(.AWIDTH(11),.RWIDTH(6)) settings_bus_16LE +   settings_bus_16LE #(.AWIDTH(11),.RWIDTH(8)) settings_bus_16LE       (.wb_clk(wb_clk),.wb_rst(wb_rst),.wb_adr_i(s8_adr),.wb_dat_i(s8_dat_mosi),        .wb_stb_i(s8_stb),.wb_we_i(s8_we),.wb_ack_o(s8_ack),        .strobe(set_stb),.addr(set_addr),.data(set_data) );     // ///////////////////////////////////////////////////////////////////////// -   // ATR Controller -- Slave #6 - -   atr_controller16 atr_controller16 -     (.clk_i(wb_clk), .rst_i(wb_rst), -      .adr_i(s6_adr[5:0]), .sel_i(s6_sel), .dat_i(s6_dat_mosi), .dat_o(s6_dat_miso), -      .we_i(s6_we), .stb_i(s6_stb), .cyc_i(s6_cyc), .ack_o(s6_ack), -      .run_rx(run_rx0 | run_rx1), .run_tx(run_tx), .ctrl_lines(atr_lines)); - -   // /////////////////////////////////////////////////////////////////////////     // Readback mux 32 -- Slave #7 +   //compatibility number -> increment when the fpga has been sufficiently altered +   localparam compat_num = {16'd8, 16'd0}; //major, minor +     wire [31:0] reg_test32;     //this setting reg is persistent across resets, to check for fpga loaded @@ -471,7 +452,7 @@ module u1e_core        .word00(vita_time[63:32]),        .word01(vita_time[31:0]),        .word02(vita_time_pps[63:32]),    .word03(vita_time_pps[31:0]),        .word04(reg_test32),              .word05(err_status), -      .word06(32'b0),                   .word07(32'b0), +      .word06(compat_num),              .word07(gpio_readback),        .word08(32'b0),                   .word09(32'b0),        .word10(32'b0),                   .word11(32'b0),        .word12(32'b0),                   .word13(32'b0), @@ -491,7 +472,5 @@ module u1e_core     assign debug_clk = 2'b00; //{ EM_CLK, clk_fpga };     assign debug = 0; -   assign debug_gpio_0 = 0; -   assign debug_gpio_1 = 0;  endmodule // u1e_core diff --git a/fpga/usrp2/top/N2x0/u2plus_core.v b/fpga/usrp2/top/N2x0/u2plus_core.v index 4d612bfab..dd3d33b37 100644 --- a/fpga/usrp2/top/N2x0/u2plus_core.v +++ b/fpga/usrp2/top/N2x0/u2plus_core.v @@ -129,7 +129,7 @@ module u2plus_core     // External RAM     input [35:0] RAM_D_pi,     output [35:0] RAM_D_po, -   output RAM_D_poe,    +   output RAM_D_poe,     output [20:0] RAM_A,     output RAM_CE1n,     output RAM_CENn, @@ -163,6 +163,7 @@ module u2plus_core     localparam SR_TX_CTRL  = 144;   // 6     localparam SR_TX_DSP   = 160;   // 5 +   localparam SR_GPIO     = 184;   // 5        localparam SR_UDP_SM   = 192;   // 64     // FIFO Sizes, 9 = 512 lines, 10 = 1024, 11 = 2048 @@ -227,14 +228,14 @@ module u2plus_core  		.s1_addr(8'b0100_0000),.s1_mask(8'b1111_0000),  // Packet Router (16-20K)   		.s2_addr(8'b0101_0000),.s2_mask(8'b1111_1100),  // SPI  		.s3_addr(8'b0101_0100),.s3_mask(8'b1111_1100),  // I2C -		.s4_addr(8'b0101_1000),.s4_mask(8'b1111_1100),  // GPIO +		.s4_addr(8'b0101_1000),.s4_mask(8'b1111_1100),  // Unused  		.s5_addr(8'b0101_1100),.s5_mask(8'b1111_1100),  // Readback  		.s6_addr(8'b0110_0000),.s6_mask(8'b1111_0000),  // Ethernet MAC -		.s7_addr(8'b0111_0000),.s7_mask(8'b1111_0000),  // 20K-24K, Settings Bus (only uses 1K) +		.s7_addr(8'b0111_0000),.s7_mask(8'b1111_0000),  // Settings Bus (only uses 1K)  		.s8_addr(8'b1000_0000),.s8_mask(8'b1111_1100),  // PIC  		.s9_addr(8'b1000_0100),.s9_mask(8'b1111_1100),  // Unused  		.sa_addr(8'b1000_1000),.sa_mask(8'b1111_1100),  // UART -		.sb_addr(8'b1000_1100),.sb_mask(8'b1111_1100),  // ATR +		.sb_addr(8'b1000_1100),.sb_mask(8'b1111_1100),  // Unused  		.sc_addr(8'b1001_0000),.sc_mask(8'b1111_0000),  // Unused  		.sd_addr(8'b1010_0000),.sd_mask(8'b1111_0000),  // ICAP  		.se_addr(8'b1011_0000),.se_mask(8'b1111_0000),  // SPI Flash @@ -275,7 +276,11 @@ module u2plus_core        .se_dat_i(se_dat_i),.se_ack_i(se_ack),.se_err_i(0),.se_rty_i(0),        .sf_dat_o(sf_dat_o),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),        .sf_dat_i(sf_dat_i),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0)); -       + +   // Unused Slaves 9, b, c +   assign s4_ack = 0; +   assign s9_ack = 0;   assign sb_ack = 0;   assign sc_ack = 0; +        // ////////////////////////////////////////////////////////////////////////////////////////     // Reset Controller @@ -416,18 +421,21 @@ module u2plus_core     assign 	 s3_dat_i[31:8] = 24'd0;     // ///////////////////////////////////////////////////////////////////////// -   // GPIOs -- Slave #4 +   // GPIOs -   nsgpio nsgpio(.clk_i(wb_clk),.rst_i(wb_rst), -		 .cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[4:0]),.we_i(s4_we), -		 .dat_i(s4_dat_o),.dat_o(s4_dat_i),.ack_o(s4_ack), -		 .rx(run_rx0_d1 | rx_rx1_d1), .tx(run_tx), .gpio({io_tx,io_rx}) ); +   wire [31:0] gpio_readback; +    +   gpio_atr #(.BASE(SR_GPIO), .WIDTH(32))  +   gpio_atr(.clk(dsp_clk),.reset(dsp_rst), +	    .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), +	    .rx(run_rx0_d1 | run_rx1_d1), .tx(run_tx), +	    .gpio({io_tx,io_rx}), .gpio_readback(gpio_readback) );     // /////////////////////////////////////////////////////////////////////////     // Buffer Pool Status -- Slave #5        //compatibility number -> increment when the fpga has been sufficiently altered -   localparam compat_num = {16'd7, 16'd3}; //major, minor +   localparam compat_num = {16'd8, 16'd0}; //major, minor     wb_readback_mux buff_pool_status       (.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb), @@ -435,8 +443,8 @@ module u2plus_core        .word00(32'b0),.word01(32'b0),.word02(32'b0),.word03(32'b0),        .word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0), -      .word08(status),.word09(32'b0),.word10(vita_time[63:32]), -      .word11(vita_time[31:0]),.word12(compat_num),.word13(irq), +      .word08(status),.word09(gpio_readback),.word10(vita_time[63:32]), +      .word11(vita_time[31:0]),.word12(compat_num),.word13({18'b0, button, 13'b0}),        .word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0])        ); @@ -480,16 +488,20 @@ module u2plus_core     wire 	 phy_reset;     assign 	 PHY_RESETn = ~phy_reset; -   setting_reg #(.my_addr(SR_MISC+0),.width(8)) sr_clk (.clk(wb_clk),.rst(wb_rst),.strobe(s7_ack),.addr(set_addr), -				      .in(set_data),.out(clock_outs),.changed()); -   setting_reg #(.my_addr(SR_MISC+1),.width(8)) sr_ser (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(serdes_outs),.changed()); -   setting_reg #(.my_addr(SR_MISC+2),.width(8)) sr_adc (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(adc_outs),.changed()); -   setting_reg #(.my_addr(SR_MISC+4),.width(1)) sr_phy (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(phy_reset),.changed()); -   setting_reg #(.my_addr(SR_MISC+5),.width(1)) sr_bld (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(bldr_done),.changed()); +   setting_reg #(.my_addr(SR_MISC+0),.width(8)) sr_clk +     (.clk(wb_clk),.rst(wb_rst),.strobe(s7_ack),.addr(set_addr),.in(set_data),.out(clock_outs),.changed()); + +   setting_reg #(.my_addr(SR_MISC+1),.width(8)) sr_ser +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(serdes_outs),.changed()); + +   setting_reg #(.my_addr(SR_MISC+2),.width(8)) sr_adc +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(adc_outs),.changed()); + +   setting_reg #(.my_addr(SR_MISC+4),.width(1)) sr_phy +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(phy_reset),.changed()); + +   setting_reg #(.my_addr(SR_MISC+5),.width(1)) sr_bld +     (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),.out(bldr_done),.changed());     // /////////////////////////////////////////////////////////////////////////     //  LEDS @@ -500,48 +512,27 @@ module u2plus_core     wire [7:0] 	 led_src, led_sw;     wire [7:0] 	 led_hw = {run_tx, (run_rx0_d1 | run_rx1_d1), clk_status, serdes_link_up & good_sync, 1'b0}; -   setting_reg #(.my_addr(SR_MISC+3),.width(8)) sr_led (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(led_sw),.changed()); +   setting_reg #(.my_addr(SR_MISC+3),.width(8)) sr_led +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(led_sw),.changed()); -   setting_reg #(.my_addr(SR_MISC+6),.width(8), .at_reset(8'b0001_1110))  -   sr_led_src (.clk(wb_clk),.rst(wb_rst), .strobe(set_stb),.addr(set_addr), .in(set_data),.out(led_src),.changed()); +   setting_reg #(.my_addr(SR_MISC+6),.width(8), .at_reset(8'b0001_1110)) sr_led_src +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp), .in(set_data_dsp),.out(led_src),.changed());     assign 	 leds = (led_src & led_hw) | (~led_src & led_sw);     // /////////////////////////////////////////////////////////////////////////     // Interrupt Controller, Slave #8 -   // Pass interrupts on dsp_clk to wb_clk.  These need edge triggering in the pic -   wire 	 underrun_wb, overrun_wb, pps_wb; - -   oneshot_2clk underrun_1s (.clk_in(dsp_clk), .in(underrun), .clk_out(wb_clk), .out(underrun_wb)); -   oneshot_2clk overrun_1s (.clk_in(dsp_clk), .in(overrun0 | overrun1), .clk_out(wb_clk), .out(overrun_wb)); -   oneshot_2clk pps_1s (.clk_in(dsp_clk), .in(pps_int), .clk_out(wb_clk), .out(pps_wb)); -        assign irq= {{8'b0},  		{uart_tx_int[3:0], uart_rx_int[3:0]}, -		{2'b0, button, periodic_int, clk_status, serdes_link_up, 2'b00}, -		{pps_wb,overrun_wb,underrun_wb,PHY_INTn,i2c_int,spi_int,onetime_int,buffer_int}}; +		{4'b0, clk_status, 3'b0}, +		{3'b0, PHY_INTn,i2c_int,spi_int,2'b00}};     pic pic(.clk_i(wb_clk),.rst_i(wb_rst),.cyc_i(s8_cyc),.stb_i(s8_stb),.adr_i(s8_adr[4:2]),  	   .we_i(s8_we),.dat_i(s8_dat_o),.dat_o(s8_dat_i),.ack_o(s8_ack),.int_o(proc_int),  	   .irq(irq) );     // ///////////////////////////////////////////////////////////////////////// -   // Master Timer, Slave #9 - -   // No longer used, replaced with simple_timer below -   assign s9_ack = 0; -    -   // ///////////////////////////////////////////////////////////////////////// -   //  Simple Timer interrupts -   /* -   simple_timer #(.BASE(SR_SIMTIMER)) simple_timer -     (.clk(wb_clk), .reset(wb_rst), -      .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), -      .onetime_int(onetime_int), .periodic_int(periodic_int)); -   */ -   // /////////////////////////////////////////////////////////////////////////     // UART, Slave #10     quad_uart #(.TXDEPTH(3),.RXDEPTH(3)) uart  // depth of 3 is 128 entries @@ -550,24 +541,6 @@ module u2plus_core        .adr_i(sa_adr[6:2]),.dat_i(sa_dat_o),.dat_o(sa_dat_i),        .rx_int_o(uart_rx_int),.tx_int_o(uart_tx_int),        .tx_o(uart_tx_o),.rx_i(uart_rx_i),.baud_o(uart_baud_o)); -    -   // ///////////////////////////////////////////////////////////////////////// -   // ATR Controller, Slave #11 - -   /* -   atr_controller atr_controller -     (.clk_i(wb_clk),.rst_i(wb_rst), -      .adr_i(sb_adr[5:0]),.sel_i(sb_sel),.dat_i(sb_dat_o),.dat_o(sb_dat_i), -      .we_i(sb_we),.stb_i(sb_stb),.cyc_i(sb_cyc),.ack_o(sb_ack), -      .run_rx(run_rx0_d1 | run_rx1_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) ); -   */ -    -   // ////////////////////////////////////////////////////////////////////////// -   // Time Sync, Slave #12  - -   // No longer used, see time_64bit.  Still need to handle mimo time, though -   assign sc_ack = 0; -        // /////////////////////////////////////////////////////////////////////////     // ICAP for reprogramming the FPGA, Slave #13 (D) @@ -660,8 +633,8 @@ module u2plus_core     wire 	 clear_tx;     setting_reg #(.my_addr(SR_TX_CTRL+1)) sr_clear_tx -     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out(),.changed(clear_tx)); +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp), +      .in(set_data_dsp),.out(),.changed(clear_tx));     assign 	 RAM_A[20:18] = 3'b0; diff --git a/fpga/usrp2/top/USRP2/u2_core.v b/fpga/usrp2/top/USRP2/u2_core.v index 7415f68e5..d3524c304 100644 --- a/fpga/usrp2/top/USRP2/u2_core.v +++ b/fpga/usrp2/top/USRP2/u2_core.v @@ -136,7 +136,7 @@ module u2_core     // External RAM     input [17:0] RAM_D_pi, -   output [17:0] RAM_D_po,    +   output [17:0] RAM_D_po,     output RAM_D_poe,     output [18:0] RAM_A,     output RAM_CE1n, @@ -168,6 +168,7 @@ module u2_core     localparam SR_TX_CTRL  = 144;   // 6     localparam SR_TX_DSP   = 160;   // 5 +   localparam SR_GPIO     = 184;   // 5        localparam SR_UDP_SM   = 192;   // 64     // FIFO Sizes, 9 = 512 lines, 10 = 1024, 11 = 2048 @@ -233,16 +234,16 @@ module u2_core  		.s1_addr(8'b0100_0000),.s1_mask(8'b1111_0000),  // Packet Router (16-20K)   		.s2_addr(8'b0101_0000),.s2_mask(8'b1111_1100),  // SPI  		.s3_addr(8'b0101_0100),.s3_mask(8'b1111_1100),  // I2C -		.s4_addr(8'b0101_1000),.s4_mask(8'b1111_1100),  // GPIO +		.s4_addr(8'b0101_1000),.s4_mask(8'b1111_1100),  // Unused  		.s5_addr(8'b0101_1100),.s5_mask(8'b1111_1100),  // Readback  		.s6_addr(8'b0110_0000),.s6_mask(8'b1111_0000),  // Ethernet MAC -		.s7_addr(8'b0111_0000),.s7_mask(8'b1111_0000),  // 20K-24K, Settings Bus (only uses 1K) +		.s7_addr(8'b0111_0000),.s7_mask(8'b1111_0000),  // Settings Bus (only uses 1K)  		.s8_addr(8'b1000_0000),.s8_mask(8'b1111_1100),  // PIC  		.s9_addr(8'b1000_0100),.s9_mask(8'b1111_1100),  // Unused  		.sa_addr(8'b1000_1000),.sa_mask(8'b1111_1100),  // UART -		.sb_addr(8'b1000_1100),.sb_mask(8'b1111_1100),  // ATR +		.sb_addr(8'b1000_1100),.sb_mask(8'b1111_1100),  // Unused  		.sc_addr(8'b1001_0000),.sc_mask(8'b1111_0000),  // Unused -		.sd_addr(8'b1010_0000),.sd_mask(8'b1111_0000),  // SD Card access +		.sd_addr(8'b1010_0000),.sd_mask(8'b1111_0000),  // Unused  		.se_addr(8'b1011_0000),.se_mask(8'b1111_0000),  // Unused  		.sf_addr(8'b1100_0000),.sf_mask(8'b1100_0000),  // Unused  		.dw(dw),.aw(aw),.sw(sw)) wb_1master @@ -281,7 +282,12 @@ module u2_core        .se_dat_i(se_dat_i),.se_ack_i(se_ack),.se_err_i(0),.se_rty_i(0),        .sf_dat_o(sf_dat_o),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),        .sf_dat_i(sf_dat_i),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0)); -       + +   // Unused Slaves 4, 9 and b-f +   assign s4_ack = 0; +   assign s9_ack = 0;   assign sb_ack = 0;   assign sc_ack = 0; +   assign sd_ack = 0;   assign se_ack = 0;   assign fc_ack = 0; +        // ////////////////////////////////////////////////////////////////////////////////////////     // Reset Controller     system_control sysctrl (.wb_clk_i(wb_clk), // .por_i(por), @@ -421,18 +427,21 @@ module u2_core     assign 	 s3_dat_i[31:8] = 24'd0;     // ///////////////////////////////////////////////////////////////////////// -   // GPIOs -- Slave #4 +   // GPIOs -   nsgpio nsgpio(.clk_i(wb_clk),.rst_i(wb_rst), -		 .cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[4:0]),.we_i(s4_we), -		 .dat_i(s4_dat_o),.dat_o(s4_dat_i),.ack_o(s4_ack), -		 .rx(run_rx0_d1 | rx_rx1_d1), .tx(run_tx), .gpio({io_tx,io_rx}) ); +   wire [31:0] gpio_readback; +    +   gpio_atr #(.BASE(SR_GPIO), .WIDTH(32))  +   gpio_atr(.clk(dsp_clk),.reset(dsp_rst), +	    .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), +	    .rx(run_rx0_d1 | run_rx1_d1), .tx(run_tx), +	    .gpio({io_tx,io_rx}), .gpio_readback(gpio_readback) );     // /////////////////////////////////////////////////////////////////////////     // Buffer Pool Status -- Slave #5        //compatibility number -> increment when the fpga has been sufficiently altered -   localparam compat_num = {16'd7, 16'd3}; //major, minor +   localparam compat_num = {16'd8, 16'd0}; //major, minor     wb_readback_mux buff_pool_status       (.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb), @@ -440,8 +449,8 @@ module u2_core        .word00(32'b0),.word01(32'b0),.word02(32'b0),.word03(32'b0),        .word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0), -      .word08(status),.word09(32'b0),.word10(vita_time[63:32]), -      .word11(vita_time[31:0]),.word12(compat_num),.word13(irq), +      .word08(status),.word09(gpio_readback),.word10(vita_time[63:32]), +      .word11(vita_time[31:0]),.word12(compat_num),.word13(32'b0),        .word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0])        ); @@ -485,14 +494,17 @@ module u2_core     wire 	 phy_reset;     assign 	 PHY_RESETn = ~phy_reset; -   setting_reg #(.my_addr(SR_MISC+0),.width(8)) sr_clk (.clk(wb_clk),.rst(wb_rst),.strobe(s7_ack),.addr(set_addr), -				      .in(set_data),.out(clock_outs),.changed()); -   setting_reg #(.my_addr(SR_MISC+1),.width(8)) sr_ser (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(serdes_outs),.changed()); -   setting_reg #(.my_addr(SR_MISC+2),.width(8)) sr_adc (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(adc_outs),.changed()); -   setting_reg #(.my_addr(SR_MISC+4),.width(1)) sr_phy (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(phy_reset),.changed()); +   setting_reg #(.my_addr(SR_MISC+0),.width(8)) sr_clk +     (.clk(wb_clk),.rst(wb_rst),.strobe(s7_ack),.addr(set_addr),.in(set_data),.out(clock_outs),.changed()); + +   setting_reg #(.my_addr(SR_MISC+1),.width(8)) sr_ser +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(serdes_outs),.changed()); + +   setting_reg #(.my_addr(SR_MISC+2),.width(8)) sr_adc +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(adc_outs),.changed()); + +   setting_reg #(.my_addr(SR_MISC+4),.width(1)) sr_phy +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(phy_reset),.changed());     // /////////////////////////////////////////////////////////////////////////     //  LEDS @@ -503,48 +515,27 @@ module u2_core     wire [7:0] 	 led_src, led_sw;     wire [7:0] 	 led_hw = {run_tx, (run_rx0_d1 | run_rx1_d1), clk_status, serdes_link_up & good_sync, 1'b0}; -   setting_reg #(.my_addr(SR_MISC+3),.width(8)) sr_led (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr), -				      .in(set_data),.out(led_sw),.changed()); +   setting_reg #(.my_addr(SR_MISC+3),.width(8)) sr_led +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(led_sw),.changed()); -   setting_reg #(.my_addr(SR_MISC+6),.width(8), .at_reset(8'b0001_1110))  -   sr_led_src (.clk(wb_clk),.rst(wb_rst), .strobe(set_stb),.addr(set_addr), .in(set_data),.out(led_src),.changed()); +   setting_reg #(.my_addr(SR_MISC+6),.width(8), .at_reset(8'b0001_1110)) sr_led_src +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp), .in(set_data_dsp),.out(led_src),.changed());     assign 	 leds = (led_src & led_hw) | (~led_src & led_sw);     // /////////////////////////////////////////////////////////////////////////     // Interrupt Controller, Slave #8 -   // Pass interrupts on dsp_clk to wb_clk.  These need edge triggering in the pic -   wire 	 underrun_wb, overrun_wb, pps_wb; - -   oneshot_2clk underrun_1s (.clk_in(dsp_clk), .in(underrun), .clk_out(wb_clk), .out(underrun_wb)); -   oneshot_2clk overrun_1s (.clk_in(dsp_clk), .in(overrun0 | overrun1), .clk_out(wb_clk), .out(overrun_wb)); -   oneshot_2clk pps_1s (.clk_in(dsp_clk), .in(pps_int), .clk_out(wb_clk), .out(pps_wb)); -        assign irq= {{8'b0}, -		{8'b0}, -		{2'b0, good_sync, periodic_int, clk_status, serdes_link_up, uart_tx_int, uart_rx_int}, -		{pps_wb,overrun_wb,underrun_wb,PHY_INTn,i2c_int,spi_int,onetime_int,buffer_int}}; +		{3'b0, uart_tx_int, 2'b0, uart_rx_int}, +		{4'b0, clk_status, 3'b0}, +		{3'b0, PHY_INTn,i2c_int,spi_int,2'b00}};     pic pic(.clk_i(wb_clk),.rst_i(wb_rst),.cyc_i(s8_cyc),.stb_i(s8_stb),.adr_i(s8_adr[4:2]),  	   .we_i(s8_we),.dat_i(s8_dat_o),.dat_o(s8_dat_i),.ack_o(s8_ack),.int_o(proc_int),  	   .irq(irq) );     // ///////////////////////////////////////////////////////////////////////// -   // Master Timer, Slave #9 - -   // No longer used, replaced with simple_timer below -   assign s9_ack = 0; -    -   // ///////////////////////////////////////////////////////////////////////// -   //  Simple Timer interrupts -   /* -   simple_timer #(.BASE(SR_SIMTIMER)) simple_timer -     (.clk(wb_clk), .reset(wb_rst), -      .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), -      .onetime_int(onetime_int), .periodic_int(periodic_int)); -   */ -   // /////////////////////////////////////////////////////////////////////////     // UART, Slave #10     simple_uart #(.TXDEPTH(3),.RXDEPTH(3)) uart  // depth of 3 is 128 entries @@ -553,36 +544,7 @@ module u2_core        .adr_i(sa_adr[4:2]),.dat_i(sa_dat_o),.dat_o(sa_dat_i),        .rx_int_o(uart_rx_int),.tx_int_o(uart_tx_int),        .tx_o(uart_tx_o),.rx_i(uart_rx_i),.baud_o(uart_baud_o)); -    -   // ///////////////////////////////////////////////////////////////////////// -   // ATR Controller, Slave #11 -   /* -   atr_controller atr_controller -     (.clk_i(wb_clk),.rst_i(wb_rst), -      .adr_i(sb_adr[5:0]),.sel_i(sb_sel),.dat_i(sb_dat_o),.dat_o(sb_dat_i), -      .we_i(sb_we),.stb_i(sb_stb),.cyc_i(sb_cyc),.ack_o(sb_ack), -      .run_rx(run_rx0_d1 | run_rx1_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) ); -   */ -    -   // ////////////////////////////////////////////////////////////////////////// -   // Time Sync, Slave #12  - -   // No longer used, see time_64bit.  Still need to handle mimo time, though -   assign sc_ack = 0; -    -   // ///////////////////////////////////////////////////////////////////////// -   // SD Card Reader / Writer, Slave #13 -   /* -   sd_spi_wb sd_spi_wb -     (.clk(wb_clk),.rst(wb_rst), -      .sd_clk(sd_clk),.sd_csn(sd_csn),.sd_mosi(sd_mosi),.sd_miso(sd_miso), -      .wb_cyc_i(sd_cyc),.wb_stb_i(sd_stb),.wb_we_i(sd_we), -      .wb_adr_i(sd_adr[3:2]),.wb_dat_i(sd_dat_o[7:0]),.wb_dat_o(sd_dat_i[7:0]), -      .wb_ack_o(sd_ack) ); -     -   assign sd_dat_i[31:8] = 0; -    */     // /////////////////////////////////////////////////////////////////////////     // ADC Frontend     wire [23:0] 	 adc_i, adc_q; @@ -659,8 +621,8 @@ module u2_core     wire 	 clear_tx;     setting_reg #(.my_addr(SR_TX_CTRL+1)) sr_clear_tx -     (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out(),.changed(clear_tx)); +     (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp), +      .in(set_data_dsp),.out(),.changed(clear_tx));     ext_fifo #(.EXT_WIDTH(18),.INT_WIDTH(36),.RAM_DEPTH(19),.FIFO_DEPTH(19))        ext_fifo_i1 diff --git a/fpga/usrp2/vrt/vita_rx_chain.v b/fpga/usrp2/vrt/vita_rx_chain.v index 1986743b3..8b41e5fa8 100644 --- a/fpga/usrp2/vrt/vita_rx_chain.v +++ b/fpga/usrp2/vrt/vita_rx_chain.v @@ -50,11 +50,32 @@ module vita_rx_chain        .data_o(rx_data_int), .src_rdy_o(rx_src_rdy_int), .dst_rdy_i(rx_dst_rdy_int),        .debug_rx(vrf_debug) ); -   dsp_framer36 #(.BUF_SIZE(FIFOSIZE),  -		  .PORT_SEL(UNIT),  -		  .PROT_ENG_FLAGS(PROT_ENG_FLAGS)) dsp0_framer36 -     (.clk(clk), .reset(reset), .clear(clear), +   wire [FIFOSIZE-1:0] access_adr, access_len; +   wire 	       access_we, access_stb, access_ok, access_done, access_skip_read; +   wire [35:0] 	       dsp_to_buf, buf_to_dsp; +   wire [35:0] 	       rx_data_int2; +   wire 	       rx_src_rdy_int2, rx_dst_rdy_int2; +    +   double_buffer #(.BUF_SIZE(FIFOSIZE)) db +     (.clk(clk),.reset(reset),.clear(clear), +      .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +      .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +      .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp), +        .data_i(rx_data_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int), +      .data_o(rx_data_int2), .src_rdy_o(rx_src_rdy_int2), .dst_rdy_i(rx_dst_rdy_int2)); + +   dspengine_16to8 #(.BASE(BASE+9), .BUF_SIZE(FIFOSIZE)) dspengine_16to8 +     (.clk(clk),.reset(reset),.clear(clear), +      .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), +      .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),  +      .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),  +      .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf)); +    +   add_routing_header #(.PORT_SEL(UNIT),  +			.PROT_ENG_FLAGS(PROT_ENG_FLAGS)) dsp_routing_header +     (.clk(clk), .reset(reset), .clear(clear), +      .data_i(rx_data_int2), .src_rdy_i(rx_src_rdy_int2), .dst_rdy_o(rx_dst_rdy_int2),        .data_o(rx_data_o), .src_rdy_o(rx_src_rdy_o), .dst_rdy_i(rx_dst_rdy_i) );     assign debug = vrc_debug; //  | vrf_debug; | 
