diff options
author | Matt Ettus <matt@ettus.com> | 2010-10-14 10:39:46 -0700 |
---|---|---|
committer | Matt Ettus <matt@ettus.com> | 2011-05-26 17:31:19 -0700 |
commit | d3f97446e7cd6a12050101310d5c0b09197d1788 (patch) | |
tree | e096c8edc970bacee8b39ef7229fbb5d4cf50737 /usrp2/control_lib | |
parent | 6f19b5f935117dbce949c21c7719d6c125fd3d15 (diff) | |
download | uhd-d3f97446e7cd6a12050101310d5c0b09197d1788.tar.gz uhd-d3f97446e7cd6a12050101310d5c0b09197d1788.tar.bz2 uhd-d3f97446e7cd6a12050101310d5c0b09197d1788.zip |
fifo to wb should be functionally complete, needs testing
Diffstat (limited to 'usrp2/control_lib')
-rw-r--r-- | usrp2/control_lib/fifo_to_wb.v | 162 |
1 files changed, 141 insertions, 21 deletions
diff --git a/usrp2/control_lib/fifo_to_wb.v b/usrp2/control_lib/fifo_to_wb.v index fdc76f89e..21d3945da 100644 --- a/usrp2/control_lib/fifo_to_wb.v +++ b/usrp2/control_lib/fifo_to_wb.v @@ -1,34 +1,154 @@ module fifo_to_wb - (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, - output [10:0] wb_adr_o, output [15:0] wb_dat_mosi, input [15:0] wb_dat_miso, - output wb_sel_o, output wb_cyc_o, output wb_stb_o, output wb_we_o, input wb_ack_i, - output [31:0] debug0, output [31:0] debug1); - - wire [35:0] ctrl_data, resp_data; - wire ctrl_src_rdy, ctrl_dst_rdy, resp_src_rdy, resp_dst_rdy; + #(parameter PKT_LEN = 16) + (input clk, input reset, input clear, + input [17:0] data_i, input src_rdy_i, output dst_rdy_o, + output [17:0] data_o, output src_rdy_o, input dst_rdy_i, + output reg [15:0] wb_adr_o, output [15:0] wb_dat_mosi, input [15:0] wb_dat_miso, + output wb_sel_o, output wb_cyc_o, output wb_stb_o, output wb_we_o, input wb_ack_i, + input [7:0] triggers, + output [31:0] debug0, output [31:0] debug1); + + wire [17:0] ctrl_data; + reg [17:0] resp_data; + wire ctrl_src_rdy, ctrl_dst_rdy, resp_src_rdy, resp_dst_rdy; - fifo_short #(.WIDTH(36)) ctrl_sfifo + fifo_short #(.WIDTH(18)) ctrl_sfifo (.clk(clk), .reset(reset), .clear(clear), .datain(data_i), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), .dataout(ctrl_data), .src_rdy_o(ctrl_src_rdy), .dst_rdy_i(ctrl_dst_rdy)); - - fifo_short #(.WIDTH(36)) resp_sfifo + + fifo_short #(.WIDTH(18)) resp_sfifo (.clk(clk), .reset(reset), .clear(clear), .datain(resp_data), .src_rdy_i(resp_src_rdy), .dst_rdy_o(resp_dst_rdy), .dataout(data_o), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); - // Loopback control packets + // Need a programmable state machine here. The program is the fifo contents. + // All words are 16 bits wide + // Word 0 Command { Read, Write, Triggers[5:0], Seqno [7:0] } + // Word 1 Length + // Word 2 Address LSW + // Word 3 Address MSW (should all be 0) - assign resp_data = ctrl_data; - assign resp_src_rdy = ctrl_src_rdy; - assign ctrl_dst_rdy = resp_dst_rdy; - - assign debug0 = ctrl_data[31:0]; - assign debug1 = { ctrl_src_rdy, ctrl_dst_rdy, resp_src_rdy, resp_dst_rdy, ctrl_data[35:31] }; - -endmodule // fifo_to_wb + localparam RESP_IDLE = 0; + localparam RESP_LEN = 1; + localparam RESP_ADDR_LSW = 2; + localparam RESP_ADDR_MSW = 3; + localparam RESP_WRITE = 4; + localparam RESP_DUMP = 5; + localparam RESP_WAIT_READ = 6; + localparam RESP_RCMD = 7; + localparam RESP_RLEN = 8; + localparam RESP_READ = 9; + + reg [3:0] resp_state; + reg rd, wr; + reg [15:0] base_addr; + reg [15:0] length; + reg [15:0] count; + reg [7:0] seqnum; + reg [5:0] which_trig; + + always @(posedge clk) + if(reset | clear) + resp_state <= RESP_IDLE; + else + case(resp_state) + RESP_IDLE : + if(ctrl_src_rdy) + begin + { rd, wr, which_trig[5:0], seqnum[7:0] } <= ctrl_data[15:0]; + if(ctrl_data[16]) // WAIT for start of packet, clean out otherwise + resp_state <= RESP_LEN; + end + RESP_LEN : + if(ctrl_src_rdy) + begin + length <= ctrl_data[15:0]; + count <= ctrl_data[15:0]; + resp_state <= RESP_ADDR_LSW; + end + RESP_ADDR_LSW : + if(ctrl_src_rdy) + begin + base_addr <= ctrl_data[15:0]; + wb_adr_o <= ctrl_data[15:0]; + resp_state <= RESP_ADDR_MSW; + end + RESP_ADDR_MSW : + if(ctrl_src_rdy) + if(wr) + resp_state <= RESP_WRITE; + else + resp_state <= RESP_DUMP; + RESP_WRITE : + if(ctrl_src_rdy & wb_ack_i) + if(count==1) + if(ctrl_data[17]) //eof + resp_state <= RESP_IDLE; + else // clean out padding + resp_state <= RESP_DUMP; + else + begin + wb_adr_o <= wb_adr_o + 2; + count <= count - 1; + end + RESP_DUMP : + if(ctrl_src_rdy & ctrl_data[17]) + if(rd) + resp_state <= RESP_WAIT_READ; + else + resp_state <= RESP_IDLE; + RESP_WAIT_READ : + begin + wb_adr_o <= base_addr; + count <= length; + if( &(triggers | ~which_trig) ) + resp_state <= RESP_RCMD; + end + RESP_RCMD : + if(resp_dst_rdy) + resp_state <= RESP_RLEN; + RESP_RLEN : + if(resp_dst_rdy) + resp_state <= RESP_READ; + RESP_READ : + if(resp_dst_rdy & wb_ack_i) + if(count==1) + resp_state <= RESP_IDLE; + else + begin + wb_adr_o <= wb_adr_o + 2; + count <= count - 1; + end + endcase // case (resp_state) + always @* + case(resp_state) + RESP_RCMD : resp_data <= { 2'b01, 8'hAA, seqnum }; + RESP_RLEN : resp_data <= { 2'b00, length }; + default : resp_data <= { (count==1), 1'b0, wb_dat_miso }; + endcase // case (resp_state) + + assign ctrl_dst_rdy = (resp_state == RESP_IDLE) | + (resp_state == RESP_LEN) | + (resp_state == RESP_ADDR_LSW) | + (resp_state == RESP_ADDR_MSW) | + ((resp_state == RESP_WRITE) & wb_ack_i) | + (resp_state == RESP_DUMP); + + assign resp_src_rdy = (resp_state == RESP_RCMD) | + (resp_state == RESP_RLEN) | + ((resp_state == RESP_READ) & wb_ack_i); + + assign wb_dat_mosi = ctrl_data[15:0]; + assign wb_we_o = (resp_state == RESP_WRITE); + assign wb_cyc_o = wb_stb_o; + assign wb_sel_o = 2'b11; + assign wb_stb_o = (ctrl_src_rdy & (resp_state == RESP_WRITE)) | (resp_dst_rdy & (resp_state == RESP_READ)); + + assign debug0 = { 14'd0, ctrl_data[17:0] }; + assign debug1 = { ctrl_src_rdy, ctrl_dst_rdy, resp_src_rdy, resp_dst_rdy, 2'b00, ctrl_data[17:16] }; + +endmodule // fifo_to_wb |