aboutsummaryrefslogtreecommitdiffstats
path: root/fpga
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-12-29 14:13:10 -0800
committerJosh Blum <josh@joshknows.com>2010-12-29 14:13:10 -0800
commita86bdc1ab187d075d76f8640ff2ea4c69b1d28e6 (patch)
treeeec0cec941d825ad38836dac8782fd69f60bebe5 /fpga
parent55556d641ec1d8e70b53f54998cd5878ce45a2e0 (diff)
parent64157121ed3a8af38f32d847a937c4f82ec92ebe (diff)
downloaduhd-a86bdc1ab187d075d76f8640ff2ea4c69b1d28e6.tar.gz
uhd-a86bdc1ab187d075d76f8640ff2ea4c69b1d28e6.tar.bz2
uhd-a86bdc1ab187d075d76f8640ff2ea4c69b1d28e6.zip
Merge branch 'fpga_next' into next
Diffstat (limited to 'fpga')
-rw-r--r--fpga/usrp2/fifo/Makefile.srcs1
-rw-r--r--fpga/usrp2/fifo/buffer_int.v1
-rw-r--r--fpga/usrp2/fifo/buffer_int2.v173
-rw-r--r--fpga/usrp2/fifo/packet_router.v188
4 files changed, 198 insertions, 165 deletions
diff --git a/fpga/usrp2/fifo/Makefile.srcs b/fpga/usrp2/fifo/Makefile.srcs
index 5552fbd51..f0b5b7bae 100644
--- a/fpga/usrp2/fifo/Makefile.srcs
+++ b/fpga/usrp2/fifo/Makefile.srcs
@@ -7,6 +7,7 @@
##################################################
FIFO_SRCS = $(abspath $(addprefix $(BASE_DIR)/../fifo/, \
buffer_int.v \
+buffer_int2.v \
buffer_pool.v \
crossbar36.v \
dsp_framer36.v \
diff --git a/fpga/usrp2/fifo/buffer_int.v b/fpga/usrp2/fifo/buffer_int.v
index b45ed3532..49ded8c8d 100644
--- a/fpga/usrp2/fifo/buffer_int.v
+++ b/fpga/usrp2/fifo/buffer_int.v
@@ -14,7 +14,6 @@ module buffer_int
output done,
output error,
output idle,
- output [1:0] flag,
// Buffer Interface
output en_o,
diff --git a/fpga/usrp2/fifo/buffer_int2.v b/fpga/usrp2/fifo/buffer_int2.v
new file mode 100644
index 000000000..765b125fb
--- /dev/null
+++ b/fpga/usrp2/fifo/buffer_int2.v
@@ -0,0 +1,173 @@
+
+// FIFO Interface to the 2K buffer RAMs
+// Read port is read-acknowledge
+// FIXME do we want to be able to interleave reads and writes?
+
+module buffer_int2
+ #(parameter BASE = 0,
+ parameter BUF_SIZE = 9)
+ (input clk, input rst,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ output [31:0] status,
+
+ // Wishbone interface to RAM
+ input wb_clk_i,
+ input wb_rst_i,
+ input wb_we_i,
+ input wb_stb_i,
+ input [15:0] wb_adr_i,
+ input [31:0] wb_dat_i,
+ output [31:0] wb_dat_o,
+ output reg wb_ack_o,
+
+ // Write FIFO Interface
+ input [35:0] wr_data_i,
+ input wr_ready_i,
+ output wr_ready_o,
+
+ // Read FIFO Interface
+ output [35:0] rd_data_o,
+ output rd_ready_o,
+ input rd_ready_i
+ );
+
+ reg [BUF_SIZE-1:0] rd_addr, wr_addr;
+ wire [31:0] ctrl;
+ wire wr_done, wr_error, wr_idle;
+ wire rd_done, rd_error, rd_idle;
+ wire we, en, go;
+
+ reg [BUF_SIZE-1:0] lastline;
+ wire read = ctrl[3];
+ wire rd_clear = ctrl[2];
+ wire write = ctrl[1];
+ wire wr_clear = ctrl[0];
+
+ reg [2:0] rd_state, wr_state;
+ reg rd_sop, rd_eop;
+ wire wr_sop, wr_eop;
+ reg [1:0] rd_occ;
+ wire [1:0] wr_occ;
+
+ localparam IDLE = 3'd0;
+ localparam PRE_READ = 3'd1;
+ localparam READING = 3'd2;
+ localparam WRITING = 3'd3;
+ localparam ERROR = 3'd4;
+ localparam DONE = 3'd5;
+
+ // read state machine
+ always @(posedge clk)
+ if(rst | (rd_clear & go))
+ begin
+ rd_state <= IDLE;
+ rd_sop <= 0;
+ rd_eop <= 0;
+ rd_occ <= 0;
+ end
+ else
+ case(rd_state)
+ IDLE :
+ if(go & read)
+ begin
+ rd_addr <= 0;
+ rd_state <= PRE_READ;
+ lastline <= ctrl[15+BUF_SIZE:16];
+ end
+
+ PRE_READ :
+ begin
+ rd_state <= READING;
+ rd_addr <= rd_addr + 1;
+ rd_occ <= 2'b00;
+ rd_sop <= 1;
+ rd_eop <= 0;
+ end
+
+ READING :
+ if(rd_ready_i)
+ begin
+ rd_sop <= 0;
+ rd_addr <= rd_addr + 1;
+ if(rd_addr == lastline)
+ begin
+ rd_eop <= 1;
+ // FIXME assign occ here
+ rd_occ <= 0;
+ end
+ else
+ rd_eop <= 0;
+ if(rd_eop)
+ rd_state <= DONE;
+ end
+
+ endcase // case(rd_state)
+
+ // write state machine
+ always @(posedge clk)
+ if(rst | (wr_clear & go))
+ wr_state <= IDLE;
+ else
+ case(wr_state)
+ IDLE :
+ if(go & write)
+ begin
+ wr_addr <= 0;
+ wr_state <= WRITING;
+ end
+
+ WRITING :
+ if(wr_ready_i)
+ begin
+ wr_addr <= wr_addr + 1;
+ if(wr_sop & wr_eop)
+ wr_state <= ERROR; // Should save OCC flags here
+ else if(wr_eop)
+ wr_state <= DONE;
+ end // if (wr_ready_i)
+ endcase // case(wr_state)
+
+ assign rd_data_o[35:32] = { rd_occ[1:0], rd_eop, rd_sop };
+ assign rd_ready_o = (rd_state == READING);
+
+ assign wr_sop = wr_data_i[32];
+ assign wr_eop = wr_data_i[33];
+ assign wr_occ = wr_data_i[35:34];
+ assign wr_ready_o = (wr_state == WRITING);
+
+ assign we = (wr_state == WRITING); // always write to avoid timing issue
+ assign en = ~((rd_state==READING)& ~rd_ready_i); // FIXME potential critical path
+
+ assign rd_done = (rd_state == DONE);
+ assign wr_done = (wr_state == DONE);
+ assign rd_error = (rd_state == ERROR);
+ assign wr_error = (wr_state == ERROR);
+ assign rd_idle = (rd_state == IDLE);
+ assign wr_idle = (wr_state == IDLE);
+
+ ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer_in // CPU reads here
+ (.clka(wb_clk_i),.ena(wb_stb_i),.wea(1'b0),
+ .addra(wb_adr_i[BUF_SIZE+1:2]),.dia(0),.doa(wb_dat_o),
+ .clkb(clk),.enb(1'b1),.web(we),
+ .addrb(wr_addr),.dib(wr_data_i[31:0]),.dob());
+
+ ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer_out // CPU writes here
+ (.clka(wb_clk_i),.ena(wb_stb_i),.wea(wb_we_i),
+ .addra(wb_adr_i[BUF_SIZE+1:2]),.dia(wb_dat_i),.doa(),
+ .clkb(clk),.enb(en),.web(1'b0),
+ .addrb(rd_addr),.dib(0),.dob(rd_data_o[31:0]));
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ wb_ack_o <= 0;
+ else
+ wb_ack_o <= wb_stb_i & ~wb_ack_o;
+
+ setting_reg #(.my_addr(BASE))
+ sreg(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(ctrl),.changed(go));
+
+ assign status = { {(16-BUF_SIZE){1'b0}},wr_addr,
+ 8'b0,1'b0,rd_idle,rd_error,rd_done, 1'b0,wr_idle,wr_error,wr_done};
+
+endmodule // buffer_int2
diff --git a/fpga/usrp2/fifo/packet_router.v b/fpga/usrp2/fifo/packet_router.v
index ade83bb87..ff1f80927 100644
--- a/fpga/usrp2/fifo/packet_router.v
+++ b/fpga/usrp2/fifo/packet_router.v
@@ -13,7 +13,7 @@ module packet_router
input [15:0] wb_adr_i,
input [31:0] wb_dat_i,
output [31:0] wb_dat_o,
- output reg wb_ack_o,
+ output wb_ack_o,
output wb_err_o,
output wb_rty_o,
@@ -45,11 +45,6 @@ module packet_router
assign wb_err_o = 1'b0; // Unused for now
assign wb_rty_o = 1'b0; // Unused for now
- always @(posedge wb_clk_i)
- wb_ack_o <= wb_stb_i & ~wb_ack_o;
-
- //which buffer: 0 = CPU read buffer, 1 = CPU write buffer
- wire which_buf = wb_adr_i[BUF_SIZE+2];
////////////////////////////////////////////////////////////////////
// CPU interface to this packet router
@@ -74,11 +69,10 @@ module packet_router
//setting register for mode control
wire [31:0] _sreg_mode_ctrl;
wire master_mode_flag = _sreg_mode_ctrl[0];
- wire mode_changed;
setting_reg #(.my_addr(CTRL_BASE+0)) sreg_mode_ctrl(
.clk(stream_clk),.rst(stream_rst),
.strobe(set_stb),.addr(set_addr),.in(set_data),
- .out(_sreg_mode_ctrl),.changed(mode_changed)
+ .out(_sreg_mode_ctrl),.changed()
);
//setting register to program the IP address
@@ -97,33 +91,11 @@ module packet_router
.out({dsp1_udp_port, dsp0_udp_port}),.changed()
);
- //setting register for CPU output handshake
- wire [31:0] _sreg_cpu_out_ctrl;
- wire cpu_out_hs_ctrl = _sreg_cpu_out_ctrl[0];
- setting_reg #(.my_addr(CTRL_BASE+3)) sreg_cpu_out_ctrl(
- .clk(stream_clk),.rst(stream_rst | mode_changed),
- .strobe(set_stb),.addr(set_addr),.in(set_data),
- .out(_sreg_cpu_out_ctrl),.changed()
- );
-
- //setting register for CPU input handshake
- wire [31:0] _sreg_cpu_inp_ctrl;
- wire cpu_inp_hs_ctrl = _sreg_cpu_inp_ctrl[0];
- wire [BUF_SIZE-1:0] cpu_inp_line_count = _sreg_cpu_inp_ctrl[BUF_SIZE-1+16:0+16];
- setting_reg #(.my_addr(CTRL_BASE+4)) sreg_cpu_inp_ctrl(
- .clk(stream_clk),.rst(stream_rst | mode_changed),
- .strobe(set_stb),.addr(set_addr),.in(set_data),
- .out(_sreg_cpu_inp_ctrl),.changed()
- );
-
//assign status output signals
- wire cpu_out_hs_stat;
- assign status[0] = cpu_out_hs_stat;
- wire [BUF_SIZE-1:0] cpu_out_line_count;
- assign status[BUF_SIZE-1+16:0+16] = cpu_out_line_count;
- wire cpu_inp_hs_stat;
- assign status[1] = cpu_inp_hs_stat;
- assign status[8] = master_mode_flag; //for the host to readback
+ wire [31:0] cpu_iface_status;
+ assign status = {
+ cpu_iface_status[31:9], master_mode_flag, cpu_iface_status[7:0]
+ };
////////////////////////////////////////////////////////////////////
// Communication input source crossbar
@@ -232,139 +204,27 @@ module packet_router
);
////////////////////////////////////////////////////////////////////
- // Interface CPU output to memory mapped wishbone
+ // Interface CPU to memory mapped wishbone
////////////////////////////////////////////////////////////////////
- localparam CPU_OUT_STATE_WAIT_SOF = 0;
- localparam CPU_OUT_STATE_WAIT_EOF = 1;
- localparam CPU_OUT_STATE_WAIT_CTRL_HI = 2;
- localparam CPU_OUT_STATE_WAIT_CTRL_LO = 3;
-
- reg [1:0] cpu_out_state;
- reg [BUF_SIZE-1:0] cpu_out_addr;
- assign cpu_out_line_count = cpu_out_addr;
- wire [BUF_SIZE-1:0] cpu_out_addr_next = cpu_out_addr + 1'b1;
-
- assign cpu_out_ready = (
- cpu_out_state == CPU_OUT_STATE_WAIT_SOF ||
- cpu_out_state == CPU_OUT_STATE_WAIT_EOF
- )? 1'b1 : 1'b0;
- assign cpu_out_hs_stat = (cpu_out_state == CPU_OUT_STATE_WAIT_CTRL_HI)? 1'b1 : 1'b0;
-
- RAMB16_S36_S36 cpu_out_buff(
- //port A = wishbone memory mapped address space (output only)
- .DOA(wb_dat_o),.ADDRA(wb_adr_i[BUF_SIZE+1:2]),.CLKA(wb_clk_i),.DIA(36'b0),.DIPA(4'h0),
- .ENA(wb_stb_i & (which_buf == 1'b0)),.SSRA(0),.WEA(wb_we_i),
- //port B = packet router interface to CPU (input only)
- .DOB(),.ADDRB(cpu_out_addr),.CLKB(stream_clk),.DIB(cpu_out_data[31:0]),.DIPB(4'h0),
- .ENB(cpu_out_ready & cpu_out_valid),.SSRB(0),.WEB(cpu_out_ready & cpu_out_valid)
+ buffer_int2 #(.BASE(CTRL_BASE+3), .BUF_SIZE(BUF_SIZE)) cpu_to_wb(
+ .clk(stream_clk), .rst(stream_rst | stream_clr),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .status(cpu_iface_status),
+ // Wishbone interface to RAM
+ .wb_clk_i(wb_clk_i), .wb_rst_i(wb_rst_i),
+ .wb_we_i(wb_we_i), .wb_stb_i(wb_stb_i),
+ .wb_adr_i(wb_adr_i), .wb_dat_i(wb_dat_i),
+ .wb_dat_o(wb_dat_o), .wb_ack_o(wb_ack_o),
+ // Write FIFO Interface (from PR and into WB)
+ .wr_data_i(cpu_out_data),
+ .wr_ready_i(cpu_out_valid),
+ .wr_ready_o(cpu_out_ready),
+ // Read FIFO Interface (from WB and into PR)
+ .rd_data_o(cpu_inp_data),
+ .rd_ready_o(cpu_inp_valid),
+ .rd_ready_i(cpu_inp_ready)
);
- always @(posedge stream_clk)
- if(stream_rst | stream_clr | mode_changed) begin
- cpu_out_state <= CPU_OUT_STATE_WAIT_SOF;
- cpu_out_addr <= 0;
- end
- else begin
- case(cpu_out_state)
- CPU_OUT_STATE_WAIT_SOF: begin
- if (cpu_out_ready & cpu_out_valid & cpu_out_data[32]) begin
- cpu_out_state <= CPU_OUT_STATE_WAIT_EOF;
- cpu_out_addr <= cpu_out_addr_next;
- end
- end
-
- CPU_OUT_STATE_WAIT_EOF: begin
- if (cpu_out_ready & cpu_out_valid & cpu_out_data[33]) begin
- cpu_out_state <= CPU_OUT_STATE_WAIT_CTRL_HI;
- end
- if (cpu_out_ready & cpu_out_valid) begin
- cpu_out_addr <= cpu_out_addr_next;
- end
- end
-
- CPU_OUT_STATE_WAIT_CTRL_HI: begin
- if (cpu_out_hs_ctrl == 1'b1) begin
- cpu_out_state <= CPU_OUT_STATE_WAIT_CTRL_LO;
- end
- end
-
- CPU_OUT_STATE_WAIT_CTRL_LO: begin
- if (cpu_out_hs_ctrl == 1'b0) begin
- cpu_out_state <= CPU_OUT_STATE_WAIT_SOF;
- end
- cpu_out_addr <= 0; //reset the address counter
- end
-
- endcase //cpu_out_state
- end
-
- ////////////////////////////////////////////////////////////////////
- // Interface CPU input to memory mapped wishbone
- ////////////////////////////////////////////////////////////////////
- localparam CPU_INP_STATE_WAIT_CTRL_HI = 0;
- localparam CPU_INP_STATE_WAIT_CTRL_LO = 1;
- localparam CPU_INP_STATE_UNLOAD = 2;
-
- reg [1:0] cpu_inp_state;
- reg [BUF_SIZE-1:0] cpu_inp_addr;
- wire [BUF_SIZE-1:0] cpu_inp_addr_next = cpu_inp_addr + 1'b1;
-
- reg [BUF_SIZE-1:0] cpu_inp_line_count_reg;
-
- assign cpu_inp_data[35:32] =
- (cpu_inp_addr == 1 )? 4'b0001 : (
- (cpu_inp_addr == cpu_inp_line_count_reg)? 4'b0010 : (
- 4'b0000));
-
- wire cpu_inp_enb = (cpu_inp_state == CPU_INP_STATE_UNLOAD)? (cpu_inp_ready & cpu_inp_valid) : 1'b1;
- assign cpu_inp_valid = (cpu_inp_state == CPU_INP_STATE_UNLOAD)? 1'b1 : 1'b0;
- assign cpu_inp_hs_stat = (cpu_inp_state == CPU_INP_STATE_WAIT_CTRL_HI)? 1'b1 : 1'b0;
-
- RAMB16_S36_S36 cpu_inp_buff(
- //port A = wishbone memory mapped address space (input only)
- .DOA(),.ADDRA(wb_adr_i[BUF_SIZE+1:2]),.CLKA(wb_clk_i),.DIA(wb_dat_i),.DIPA(4'h0),
- .ENA(wb_stb_i & (which_buf == 1'b1)),.SSRA(0),.WEA(wb_we_i),
- //port B = packet router interface from CPU (output only)
- .DOB(cpu_inp_data[31:0]),.ADDRB(cpu_inp_addr),.CLKB(stream_clk),.DIB(36'b0),.DIPB(4'h0),
- .ENB(cpu_inp_enb),.SSRB(0),.WEB(1'b0)
- );
-
- always @(posedge stream_clk)
- if(stream_rst | stream_clr | mode_changed) begin
- cpu_inp_state <= CPU_INP_STATE_WAIT_CTRL_HI;
- cpu_inp_addr <= 0;
- end
- else begin
- case(cpu_inp_state)
- CPU_INP_STATE_WAIT_CTRL_HI: begin
- if (cpu_inp_hs_ctrl == 1'b1) begin
- cpu_inp_state <= CPU_INP_STATE_WAIT_CTRL_LO;
- end
- cpu_inp_line_count_reg <= cpu_inp_line_count;
- end
-
- CPU_INP_STATE_WAIT_CTRL_LO: begin
- if (cpu_inp_hs_ctrl == 1'b0) begin
- cpu_inp_state <= CPU_INP_STATE_UNLOAD;
- cpu_inp_addr <= cpu_inp_addr_next;
- end
- end
-
- CPU_INP_STATE_UNLOAD: begin
- if (cpu_inp_ready & cpu_inp_valid) begin
- if (cpu_inp_data[33]) begin
- cpu_inp_addr <= 0;
- cpu_inp_state <= CPU_INP_STATE_WAIT_CTRL_HI;
- end
- else begin
- cpu_inp_addr <= cpu_inp_addr_next;
- end
- end
- end
-
- endcase //cpu_inp_state
- end
-
////////////////////////////////////////////////////////////////////
// Communication input inspector
// - inspect com input and send it to DSP, EXT, CPU, or BOTH