aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control/radio_ctrl_proc.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/control/radio_ctrl_proc.v')
-rw-r--r--fpga/usrp3/lib/control/radio_ctrl_proc.v143
1 files changed, 143 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control/radio_ctrl_proc.v b/fpga/usrp3/lib/control/radio_ctrl_proc.v
new file mode 100644
index 000000000..723ba69ff
--- /dev/null
+++ b/fpga/usrp3/lib/control/radio_ctrl_proc.v
@@ -0,0 +1,143 @@
+
+
+// Radio Control Processor
+// Accepts compressed vita extension context packets of the following form:
+// { VITA Compressed Header, Stream ID }
+// { Optional 64 bit time }
+// { 16'h0, setting bus address [15:0], setting [31:0] }
+//
+// If there is a timestamp, packet is held until that time comes.
+// Goes immediately if there is no timestamp or if time has passed.
+// Sends out setting to setting bus, and then generates a response packet
+// with the same sequence number, the src/dest swapped streamid, and the actual time
+// the setting was sent.
+//
+// Note -- if t0 is the requested time, the actual send time on the setting bus is t0 + 1 cycle.
+// Note 2 -- if t1 is the actual time the setting bus, t1+2 is the reported time.
+
+module radio_ctrl_proc
+ (input clk, input reset, input clear,
+
+ input [63:0] ctrl_tdata, input ctrl_tlast, input ctrl_tvalid, output reg ctrl_tready,
+ output reg [63:0] resp_tdata, output reg resp_tlast, output resp_tvalid, input resp_tready,
+
+ input [63:0] vita_time,
+
+ output set_stb, output [7:0] set_addr, output [31:0] set_data,
+ input ready,
+
+ input [63:0] readback,
+
+ output [31:0] debug);
+
+ localparam RC_HEAD = 4'd0;
+ localparam RC_TIME = 4'd1;
+ localparam RC_DATA = 4'd2;
+ localparam RC_DUMP = 4'd3;
+ localparam RC_RESP_HEAD = 4'd4;
+ localparam RC_RESP_TIME = 4'd5;
+ localparam RC_RESP_DATA = 4'd6;
+
+ wire IS_EC = ctrl_tdata[63];
+ wire HAS_TIME = ctrl_tdata[61];
+ reg HAS_TIME_reg;
+
+ reg [3:0] rc_state;
+ reg [63:0] cmd_time;
+
+ wire now, late, go;
+ reg [11:0] seqnum;
+ reg [31:0] sid;
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ rc_state <= RC_HEAD;
+ HAS_TIME_reg <= 1'b0;
+ sid <= 32'd0;
+ seqnum <= 12'd0;
+ end
+ else
+ case(rc_state)
+ RC_HEAD :
+ if(ctrl_tvalid)
+ begin
+ sid <= ctrl_tdata[31:0];
+ seqnum <= ctrl_tdata[59:48];
+ HAS_TIME_reg <= HAS_TIME;
+ if(IS_EC)
+ if(HAS_TIME)
+ rc_state <= RC_TIME;
+ else
+ rc_state <= RC_DATA;
+ else
+ if(~ctrl_tlast)
+ rc_state <= RC_DUMP;
+ end
+
+ RC_TIME :
+ if(ctrl_tvalid)
+ if(ctrl_tlast)
+ rc_state <= RC_RESP_HEAD;
+ else if(go)
+ rc_state <= RC_DATA;
+
+ RC_DATA :
+ if(ctrl_tvalid)
+ if(ready)
+ if(ctrl_tlast)
+ rc_state <= RC_RESP_HEAD;
+ else
+ rc_state <= RC_DUMP;
+
+ RC_DUMP :
+ if(ctrl_tvalid)
+ if(ctrl_tlast)
+ rc_state <= RC_RESP_HEAD;
+
+ RC_RESP_HEAD :
+ if(resp_tready)
+ rc_state <= RC_RESP_TIME;
+
+ RC_RESP_TIME :
+ if(resp_tready)
+ rc_state <= RC_RESP_DATA;
+
+ RC_RESP_DATA:
+ if(resp_tready)
+ rc_state <= RC_HEAD;
+
+ default :
+ rc_state <= RC_HEAD;
+ endcase // case (rc_state)
+
+ always @*
+ case (rc_state)
+ RC_HEAD : ctrl_tready <= 1'b1;
+ RC_TIME : ctrl_tready <= ctrl_tlast | go;
+ RC_DATA : ctrl_tready <= ready;
+ RC_DUMP : ctrl_tready <= 1'b1;
+ default : ctrl_tready <= 1'b0;
+ endcase // case (rc_state)
+
+ time_compare time_compare
+ (.clk(clk), .reset(reset), .time_now(vita_time), .trigger_time(ctrl_tdata), .now(now), .early(), .late(late), .too_early());
+
+ assign go = now | late;
+
+ assign set_stb = (rc_state == RC_DATA) & ready & ctrl_tvalid;
+ assign set_addr = ctrl_tdata[39:32];
+ assign set_data = ctrl_tdata[31:0];
+
+ always @*
+ case (rc_state)
+ RC_RESP_HEAD : { resp_tlast, resp_tdata } <= {1'b0, 4'hA, seqnum, 16'd24, sid[15:0], sid[31:16] };
+ RC_RESP_TIME : { resp_tlast, resp_tdata } <= {1'b0, vita_time};
+ RC_RESP_DATA : { resp_tlast, resp_tdata } <= {1'b1, readback};
+ default : { resp_tlast, resp_tdata } <= 65'h0;
+ endcase // case (rc_state)
+
+ assign resp_tvalid = (rc_state == RC_RESP_HEAD) | (rc_state == RC_RESP_TIME) | (rc_state == RC_RESP_DATA);
+
+endmodule // radio_ctrl_proc
+