Merge branch 'fpga_master' into uhd_next

This commit is contained in:
Josh Blum 2011-11-07 17:09:07 -08:00
commit 11f1390bbd
27 changed files with 1342 additions and 372 deletions

View File

@ -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 \
))

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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

2
fpga/usrp2/gpif/lint Executable file
View File

@ -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

View File

@ -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 \

View File

@ -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)
out <= temp;
strobe_out <= strobe_in;
always @(posedge clk)
if(strobe_in | ~STROBED)
out <= temp;
endmodule // clip_reg

View File

@ -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),

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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));

View File

@ -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

View File

@ -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};

View File

@ -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)

View File

@ -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

View File

@ -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,75 +299,47 @@ 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
@ -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

View File

@ -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

View File

@ -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,26 +340,13 @@ 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
@ -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

View File

@ -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,47 +512,26 @@ 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
@ -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;

View File

@ -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,47 +515,26 @@ 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
@ -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

View File

@ -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;