diff options
Diffstat (limited to 'fpga/usrp2/fifo')
-rw-r--r-- | fpga/usrp2/fifo/Makefile.srcs | 1 | ||||
-rw-r--r-- | fpga/usrp2/fifo/buffer_int.v | 1 | ||||
-rw-r--r-- | fpga/usrp2/fifo/buffer_int2.v | 173 | ||||
-rw-r--r-- | fpga/usrp2/fifo/packet_router.v | 188 |
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 |