diff options
Diffstat (limited to 'fpga/usrp2/control_lib/dbsm.v')
-rw-r--r-- | fpga/usrp2/control_lib/dbsm.v | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/fpga/usrp2/control_lib/dbsm.v b/fpga/usrp2/control_lib/dbsm.v new file mode 100644 index 000000000..fea51096f --- /dev/null +++ b/fpga/usrp2/control_lib/dbsm.v @@ -0,0 +1,164 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +module dbsm + (input clk, + input reset, + input clear, + + output write_ok, + output write_ptr, + input write_done, + + output read_ok, + output read_ptr, + input read_done, + + output access_ok, + output access_ptr, + input access_done, + input access_skip_read + ); + + localparam PORT_WAIT_0 = 0; + localparam PORT_USE_0 = 1; + localparam PORT_WAIT_1 = 2; + localparam PORT_USE_1 = 3; + + reg [1:0] write_port_state, access_port_state, read_port_state; + + localparam BUFF_WRITABLE = 0; + localparam BUFF_ACCESSIBLE = 1; + localparam BUFF_READABLE = 2; + localparam BUFF_ERROR = 3; + + wire [1:0] buff_state[0:1]; + + always @(posedge clk) + if(reset | clear) + write_port_state <= PORT_WAIT_0; + else + case(write_port_state) + PORT_WAIT_0 : + if(buff_state[0]==BUFF_WRITABLE) + write_port_state <= PORT_USE_0; + PORT_USE_0 : + if(write_done) + write_port_state <= PORT_WAIT_1; + PORT_WAIT_1 : + if(buff_state[1]==BUFF_WRITABLE) + write_port_state <= PORT_USE_1; + PORT_USE_1 : + if(write_done) + write_port_state <= PORT_WAIT_0; + endcase // case (write_port_state) + + assign write_ok = (write_port_state == PORT_USE_0) | (write_port_state == PORT_USE_1); + assign write_ptr = (write_port_state == PORT_USE_1); + + always @(posedge clk) + if(reset | clear) + access_port_state <= PORT_WAIT_0; + else + case(access_port_state) + PORT_WAIT_0 : + if(buff_state[0]==BUFF_ACCESSIBLE) + access_port_state <= PORT_USE_0; + PORT_USE_0 : + if(access_done) + access_port_state <= PORT_WAIT_1; + PORT_WAIT_1 : + if(buff_state[1]==BUFF_ACCESSIBLE) + access_port_state <= PORT_USE_1; + PORT_USE_1 : + if(access_done) + access_port_state <= PORT_WAIT_0; + endcase // case (access_port_state) + + assign access_ok = (access_port_state == PORT_USE_0) | (access_port_state == PORT_USE_1); + assign access_ptr = (access_port_state == PORT_USE_1); + + always @(posedge clk) + if(reset | clear) + read_port_state <= PORT_WAIT_0; + else + case(read_port_state) + PORT_WAIT_0 : + if(buff_state[0]==BUFF_READABLE) + read_port_state <= PORT_USE_0; + PORT_USE_0 : + if(read_done) + read_port_state <= PORT_WAIT_1; + PORT_WAIT_1 : + if(buff_state[1]==BUFF_READABLE) + read_port_state <= PORT_USE_1; + PORT_USE_1 : + if(read_done) + read_port_state <= PORT_WAIT_0; + endcase // case (read_port_state) + + assign read_ok = (read_port_state == PORT_USE_0) | (read_port_state == PORT_USE_1); + assign read_ptr = (read_port_state == PORT_USE_1); + + buff_sm #(.PORT_USE_FLAG(PORT_USE_0)) buff0_sm + (.clk(clk), .reset(reset), .clear(clear), + .write_done(write_done), .access_done(access_done), .access_skip_read(access_skip_read), .read_done(read_done), + .write_port_state(write_port_state), .access_port_state(access_port_state), .read_port_state(read_port_state), + .buff_state(buff_state[0])); + + buff_sm #(.PORT_USE_FLAG(PORT_USE_1)) buff1_sm + (.clk(clk), .reset(reset), .clear(clear), + .write_done(write_done), .access_done(access_done), .access_skip_read(access_skip_read), .read_done(read_done), + .write_port_state(write_port_state), .access_port_state(access_port_state), .read_port_state(read_port_state), + .buff_state(buff_state[1])); + +endmodule // dbsm + +module buff_sm + #(parameter PORT_USE_FLAG=0) + (input clk, input reset, input clear, + input write_done, input access_done, input access_skip_read, input read_done, + input [1:0] write_port_state, input [1:0] access_port_state, input [1:0] read_port_state, + output reg [1:0] buff_state); + + localparam BUFF_WRITABLE = 0; + localparam BUFF_ACCESSIBLE = 1; + localparam BUFF_READABLE = 2; + localparam BUFF_ERROR = 3; + + always @(posedge clk) + if(reset | clear) + buff_state <= BUFF_WRITABLE; + else + case(buff_state) + BUFF_WRITABLE : + if(write_done & (write_port_state == PORT_USE_FLAG)) + buff_state <= BUFF_ACCESSIBLE; + BUFF_ACCESSIBLE : + if(access_done & (access_port_state == PORT_USE_FLAG)) + if(access_skip_read) + buff_state <= BUFF_WRITABLE; + else + buff_state <= BUFF_READABLE; + BUFF_READABLE : + if(read_done & (read_port_state == PORT_USE_FLAG)) + buff_state <= BUFF_WRITABLE; + BUFF_ERROR : + ; + endcase + +endmodule // buff_sm |