Revision c7adcbe4 usrp2/control_lib/simple_spi_core.v
| b/usrp2/control_lib/simple_spi_core.v | ||
|---|---|---|
| 50 | 50 |
parameter WIDTH = 8, |
| 51 | 51 |
|
| 52 | 52 |
//idle state of the spi clock |
| 53 |
parameter CLK_IDLE = 1,
|
|
| 53 |
parameter CLK_IDLE = 0,
|
|
| 54 | 54 |
|
| 55 | 55 |
//idle state of the serial enables |
| 56 | 56 |
parameter SEN_IDLE = 24'hffffff |
| ... | ... | |
| 64 | 64 |
|
| 65 | 65 |
//32-bit data readback |
| 66 | 66 |
output [31:0] readback, |
| 67 |
|
|
| 68 |
//done is high for one cycle after a spi transaction
|
|
| 69 |
output done,
|
|
| 67 |
|
|
| 68 |
//read is high when spi core can begin another transaction
|
|
| 69 |
output ready,
|
|
| 70 | 70 |
|
| 71 | 71 |
//spi interface, slave selects, clock, data in, data out |
| 72 | 72 |
output [WIDTH-1:0] sen, |
| ... | ... | |
| 101 | 101 |
localparam CLK_REG = 2; |
| 102 | 102 |
localparam CLK_INV = 3; |
| 103 | 103 |
localparam POST_IDLE = 4; |
| 104 |
localparam TRANS_DONE = 5; |
|
| 105 | 104 |
|
| 106 | 105 |
reg [2:0] state; |
| 107 | 106 |
|
| 108 |
assign done = (state == TRANS_DONE);
|
|
| 107 |
assign ready = (state == WAIT_TRIG);
|
|
| 109 | 108 |
|
| 110 | 109 |
//serial clock either idles or is in one of two clock states |
| 111 |
assign sclk = (state == CLK_INV)? ~CLK_IDLE : (state == CLK_REG)? CLK_IDLE : CLK_IDLE; |
|
| 110 |
reg sclk_reg; |
|
| 111 |
assign sclk = sclk_reg; |
|
| 112 | 112 |
|
| 113 | 113 |
//serial enables either idle or enabled based on state |
| 114 |
wire [23:0] sen24 = (state == WAIT_TRIG || state == TRANS_DONE)? SEN_IDLE : (SEN_IDLE ^ slave_select); |
|
| 115 |
assign sen = sen24[WIDTH-1:0]; |
|
| 114 |
wire [23:0] sen24 = (ready)? SEN_IDLE : (SEN_IDLE ^ slave_select); |
|
| 115 |
reg [WIDTH-1:0] sen_reg; |
|
| 116 |
always @(posedge clock) sen_reg <= sen24[WIDTH-1:0]; |
|
| 117 |
assign sen = sen_reg; |
|
| 116 | 118 |
|
| 117 | 119 |
//data output shift register |
| 118 | 120 |
reg [31:0] dataout_reg; |
| 119 |
wire [31:0] dataout_next = {0, dataout_reg[31:1]};
|
|
| 120 |
assign mosi = (state == CLK_INV || state == CLK_REG)? dataout_reg[0] : 0;
|
|
| 121 |
wire [31:0] dataout_next = {dataout_reg[30:0], 1'b0};
|
|
| 122 |
assign mosi = dataout_reg[31];
|
|
| 121 | 123 |
|
| 122 | 124 |
//data input shift register |
| 123 | 125 |
reg [31:0] datain_reg; |
| ... | ... | |
| 137 | 139 |
always @(posedge clock) begin |
| 138 | 140 |
if (reset) begin |
| 139 | 141 |
state <= WAIT_TRIG; |
| 142 |
sclk_reg <= CLK_IDLE; |
|
| 140 | 143 |
end |
| 141 | 144 |
else begin |
| 142 | 145 |
case (state) |
| ... | ... | |
| 144 | 147 |
WAIT_TRIG: begin |
| 145 | 148 |
if (trigger_spi) state <= PRE_IDLE; |
| 146 | 149 |
sclk_counter <= 0; |
| 150 |
sclk_reg <= CLK_IDLE; |
|
| 147 | 151 |
end |
| 148 | 152 |
|
| 149 | 153 |
PRE_IDLE: begin |
| ... | ... | |
| 151 | 155 |
sclk_counter <= sclk_counter_next; |
| 152 | 156 |
dataout_reg <= mosi_data; |
| 153 | 157 |
bit_counter <= 0; |
| 158 |
sclk_reg <= CLK_IDLE; |
|
| 154 | 159 |
end |
| 155 | 160 |
|
| 156 | 161 |
CLK_REG: begin |
| 157 | 162 |
if (sclk_counter_done) begin |
| 158 | 163 |
state <= CLK_INV; |
| 159 |
if (~datain_edge) datain_reg <= datain_next; |
|
| 160 |
if (~dataout_edge) dataout_reg <= dataout_next; |
|
| 164 |
if (datain_edge != CLK_IDLE) datain_reg <= datain_next; |
|
| 165 |
if (dataout_edge != CLK_IDLE) dataout_reg <= dataout_next; |
|
| 166 |
sclk_reg <= ~CLK_IDLE; |
|
| 161 | 167 |
end |
| 162 | 168 |
sclk_counter <= sclk_counter_next; |
| 163 | 169 |
end |
| ... | ... | |
| 166 | 172 |
if (sclk_counter_done) begin |
| 167 | 173 |
state <= (bit_counter_done)? POST_IDLE : CLK_REG; |
| 168 | 174 |
bit_counter <= bit_counter_next; |
| 169 |
if (datain_edge) datain_reg <= datain_next; |
|
| 170 |
if (dataout_edge) dataout_reg <= dataout_next; |
|
| 175 |
if (datain_edge == CLK_IDLE) datain_reg <= datain_next; |
|
| 176 |
if (dataout_edge == CLK_IDLE) dataout_reg <= dataout_next; |
|
| 177 |
sclk_reg <= CLK_IDLE; |
|
| 171 | 178 |
end |
| 172 | 179 |
sclk_counter <= sclk_counter_next; |
| 173 | 180 |
end |
| 174 | 181 |
|
| 175 | 182 |
POST_IDLE: begin |
| 176 |
if (sclk_counter_done) state <= TRANS_DONE;
|
|
| 183 |
if (sclk_counter_done) state <= WAIT_TRIG;
|
|
| 177 | 184 |
sclk_counter <= sclk_counter_next; |
| 185 |
sclk_reg <= CLK_IDLE; |
|
| 178 | 186 |
end |
| 179 | 187 |
|
| 180 | 188 |
default: state <= WAIT_TRIG; |
| ... | ... | |
| 185 | 193 |
|
| 186 | 194 |
assign debug = {
|
| 187 | 195 |
trigger_spi, state, //4 |
| 188 |
sclk, mosi, miso, done, //4
|
|
| 196 |
sclk, mosi, miso, ready, //4
|
|
| 189 | 197 |
sen[7:0], //8 |
| 190 | 198 |
1'b0, bit_counter[6:0], //8 |
| 191 | 199 |
sclk_counter_done, bit_counter_done, //2 |
Also available in: Unified diff