mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
rm : rm unused 3rd_party
This commit is contained in:
9 files changed
+4
-1408
No files matched your search
+1
-1
@@ -150,7 +150,7 @@ void main()
|
||||
ip_tim_test();
|
||||
ip_rng_test();
|
||||
ip_gpio_test();
|
||||
ip_hpuart_test();
|
||||
// ip_hpuart_test();
|
||||
ip_pwm_test();
|
||||
// ip_ps2_test();
|
||||
ip_i2c_test();
|
||||
|
||||
-279
@@ -1,279 +0,0 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// -- Adaptable modifications made for hbirdv2 SoC. --
|
||||
// Copyright 2020 Nuclei System Technology, Inc.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
|
||||
`define log2(VALUE) ((VALUE) < ( 1 ) ? 0 : (VALUE) < ( 2 ) ? 1 : (VALUE) < ( 4 ) ? 2 : (VALUE) < ( 8 ) ? 3 : (VALUE) < ( 16 ) ? 4 : (VALUE) < ( 32 ) ? 5 : (VALUE) < ( 64 ) ? 6 : (VALUE) < ( 128 ) ? 7 : (VALUE) < ( 256 ) ? 8 : (VALUE) < ( 512 ) ? 9 : (VALUE) < ( 1024 ) ? 10 : (VALUE) < ( 2048 ) ? 11 : (VALUE) < ( 4096 ) ? 12 : (VALUE) < ( 8192 ) ? 13 : (VALUE) < ( 16384 ) ? 14 : (VALUE) < ( 32768 ) ? 15 : (VALUE) < ( 65536 ) ? 16 : (VALUE) < ( 131072 ) ? 17 : (VALUE) < ( 262144 ) ? 18 : (VALUE) < ( 524288 ) ? 19 : (VALUE) < ( 1048576 ) ? 20 : (VALUE) < ( 1048576 * 2 ) ? 21 : (VALUE) < ( 1048576 * 4 ) ? 22 : (VALUE) < ( 1048576 * 8 ) ? 23 : (VALUE) < ( 1048576 * 16 ) ? 24 : 25)
|
||||
|
||||
`define SPI_STD 2'b00
|
||||
`define SPI_QUAD_TX 2'b01
|
||||
`define SPI_QUAD_RX 2'b10
|
||||
|
||||
module apb_spi_master
|
||||
#(
|
||||
parameter BUFFER_DEPTH = 10,
|
||||
parameter APB_ADDR_WIDTH = 12 //APB slaves are 4KB by default
|
||||
)
|
||||
(
|
||||
input wire HCLK,
|
||||
input wire HRESETn,
|
||||
input wire [APB_ADDR_WIDTH - 1:0] PADDR,
|
||||
input wire [31:0] PWDATA,
|
||||
input wire PWRITE,
|
||||
input wire PSEL,
|
||||
input wire PENABLE,
|
||||
output wire [31:0] PRDATA,
|
||||
output wire PREADY,
|
||||
output wire PSLVERR,
|
||||
|
||||
output wire events_o,
|
||||
|
||||
output wire spi_clk,
|
||||
output wire spi_csn0,
|
||||
output wire spi_csn1,
|
||||
output wire spi_csn2,
|
||||
output wire spi_csn3,
|
||||
output wire spi_sdo0,
|
||||
output wire spi_sdo1,
|
||||
output wire spi_sdo2,
|
||||
output wire spi_sdo3,
|
||||
output reg spi_oe0,
|
||||
output reg spi_oe1,
|
||||
output reg spi_oe2,
|
||||
output reg spi_oe3,
|
||||
input wire spi_sdi0,
|
||||
input wire spi_sdi1,
|
||||
input wire spi_sdi2,
|
||||
input wire spi_sdi3
|
||||
);
|
||||
|
||||
localparam LOG_BUFFER_DEPTH = `log2(BUFFER_DEPTH);
|
||||
|
||||
wire [7:0] spi_clk_div;
|
||||
wire spi_clk_div_valid;
|
||||
wire [31:0] spi_status;
|
||||
wire [31:0] spi_addr;
|
||||
wire [5:0] spi_addr_len;
|
||||
wire [31:0] spi_cmd;
|
||||
wire [5:0] spi_cmd_len;
|
||||
wire [15:0] spi_data_len;
|
||||
wire [15:0] spi_dummy_rd;
|
||||
wire [15:0] spi_dummy_wr;
|
||||
wire spi_swrst;
|
||||
wire spi_rd;
|
||||
wire spi_wr;
|
||||
wire spi_qrd;
|
||||
wire spi_qwr;
|
||||
wire [3:0] spi_csreg;
|
||||
wire [31:0] spi_data_tx;
|
||||
wire spi_data_tx_valid;
|
||||
wire spi_data_tx_ready;
|
||||
wire [31:0] spi_data_rx;
|
||||
wire spi_data_rx_valid;
|
||||
wire spi_data_rx_ready;
|
||||
wire [6:0] spi_ctrl_status;
|
||||
wire [31:0] spi_ctrl_data_tx;
|
||||
wire spi_ctrl_data_tx_valid;
|
||||
wire spi_ctrl_data_tx_ready;
|
||||
wire [31:0] spi_ctrl_data_rx;
|
||||
wire spi_ctrl_data_rx_valid;
|
||||
wire spi_ctrl_data_rx_ready;
|
||||
|
||||
wire [1:0] spi_mode;
|
||||
|
||||
wire s_eot;
|
||||
|
||||
wire [LOG_BUFFER_DEPTH:0] elements_tx;
|
||||
wire [LOG_BUFFER_DEPTH:0] elements_rx;
|
||||
|
||||
wire [LOG_BUFFER_DEPTH:0] s_th_tx;
|
||||
wire [LOG_BUFFER_DEPTH:0] s_th_rx;
|
||||
|
||||
wire s_rise_int_tx;
|
||||
wire s_rise_int_rx;
|
||||
wire s_int_tx;
|
||||
wire s_int_rx;
|
||||
wire s_int_en;
|
||||
wire [31:0] s_int_status;
|
||||
|
||||
|
||||
localparam FILL_BITS = 7 - LOG_BUFFER_DEPTH;
|
||||
|
||||
assign spi_status = {{FILL_BITS {1'b0}}, elements_tx, {FILL_BITS {1'b0}}, elements_rx, 9'h000, spi_ctrl_status};
|
||||
|
||||
assign s_rise_int_tx = s_int_en & (elements_tx < s_th_tx);
|
||||
assign s_rise_int_rx = s_int_en & (elements_rx > s_th_rx);
|
||||
|
||||
assign events_o = s_rise_int_tx | s_rise_int_rx;
|
||||
assign s_int_status = {s_rise_int_rx, s_rise_int_tx};
|
||||
|
||||
always @(*) begin
|
||||
spi_oe0 = 1'b0;
|
||||
spi_oe1 = 1'b0;
|
||||
spi_oe2 = 1'b0;
|
||||
spi_oe3 = 1'b0;
|
||||
|
||||
case (spi_mode)
|
||||
`SPI_STD: begin
|
||||
spi_oe0 = 1'b1;
|
||||
spi_oe1 = 1'b0;
|
||||
spi_oe2 = 1'b0;
|
||||
spi_oe3 = 1'b0;
|
||||
end
|
||||
`SPI_QUAD_TX: begin
|
||||
spi_oe0 = 1'b1;
|
||||
spi_oe1 = 1'b1;
|
||||
spi_oe2 = 1'b1;
|
||||
spi_oe3 = 1'b1;
|
||||
end
|
||||
`SPI_QUAD_RX: begin
|
||||
spi_oe0 = 1'b0;
|
||||
spi_oe1 = 1'b0;
|
||||
spi_oe2 = 1'b0;
|
||||
spi_oe3 = 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
spi_master_apb_if
|
||||
#(
|
||||
.BUFFER_DEPTH ( BUFFER_DEPTH ),
|
||||
.APB_ADDR_WIDTH ( APB_ADDR_WIDTH )
|
||||
)
|
||||
u_axiregs
|
||||
(
|
||||
.HCLK ( HCLK ),
|
||||
.HRESETn ( HRESETn ),
|
||||
.PADDR ( PADDR ),
|
||||
.PWDATA ( PWDATA ),
|
||||
.PWRITE ( PWRITE ),
|
||||
.PSEL ( PSEL ),
|
||||
.PENABLE ( PENABLE ),
|
||||
.PRDATA ( PRDATA ),
|
||||
.PREADY ( PREADY ),
|
||||
.PSLVERR ( PSLVERR ),
|
||||
|
||||
.spi_clk_div ( spi_clk_div ),
|
||||
.spi_clk_div_valid ( spi_clk_div_valid ),
|
||||
.spi_status ( spi_status ),
|
||||
.spi_addr ( spi_addr ),
|
||||
.spi_addr_len ( spi_addr_len ),
|
||||
.spi_cmd ( spi_cmd ),
|
||||
.spi_cmd_len ( spi_cmd_len ),
|
||||
.spi_data_len ( spi_data_len ),
|
||||
.spi_dummy_rd ( spi_dummy_rd ),
|
||||
.spi_dummy_wr ( spi_dummy_wr ),
|
||||
.spi_swrst ( spi_swrst ),
|
||||
.spi_rd ( spi_rd ),
|
||||
.spi_wr ( spi_wr ),
|
||||
.spi_qrd ( spi_qrd ),
|
||||
.spi_qwr ( spi_qwr ),
|
||||
.spi_csreg ( spi_csreg ),
|
||||
.spi_int_th_rx ( s_th_rx ),
|
||||
.spi_int_th_tx ( s_th_tx ),
|
||||
.spi_int_en ( s_int_en ),
|
||||
.spi_int_status ( s_int_status ),
|
||||
.spi_data_tx ( spi_data_tx ),
|
||||
.spi_data_tx_valid ( spi_data_tx_valid ),
|
||||
.spi_data_tx_ready ( spi_data_tx_ready ), //FIXME not used inside thhis module
|
||||
.spi_data_rx ( spi_data_rx ),
|
||||
.spi_data_rx_valid ( spi_data_rx_valid ),
|
||||
.spi_data_rx_ready ( spi_data_rx_ready )
|
||||
);
|
||||
|
||||
spi_master_fifo
|
||||
#(
|
||||
.DATA_WIDTH ( 32 ),
|
||||
.BUFFER_DEPTH ( BUFFER_DEPTH )
|
||||
)
|
||||
u_txfifo
|
||||
(
|
||||
.clk_i ( HCLK ),
|
||||
.rst_ni ( HRESETn ),
|
||||
.clr_i ( spi_swrst ),
|
||||
|
||||
.elements_o ( elements_tx ),
|
||||
|
||||
.data_o ( spi_ctrl_data_tx ),
|
||||
.valid_o ( spi_ctrl_data_tx_valid ),
|
||||
.ready_i ( spi_ctrl_data_tx_ready ),
|
||||
|
||||
.valid_i ( spi_data_tx_valid ),
|
||||
.data_i ( spi_data_tx ),
|
||||
.ready_o ( spi_data_tx_ready )
|
||||
);
|
||||
|
||||
spi_master_fifo
|
||||
#(
|
||||
.DATA_WIDTH ( 32 ),
|
||||
.BUFFER_DEPTH ( BUFFER_DEPTH )
|
||||
)
|
||||
u_rxfifo
|
||||
(
|
||||
.clk_i ( HCLK ),
|
||||
.rst_ni ( HRESETn ),
|
||||
.clr_i ( spi_swrst ),
|
||||
|
||||
.elements_o ( elements_rx ),
|
||||
|
||||
.data_o ( spi_data_rx ),
|
||||
.valid_o ( spi_data_rx_valid ),
|
||||
.ready_i ( spi_data_rx_ready ),
|
||||
|
||||
.valid_i ( spi_ctrl_data_rx_valid ),
|
||||
.data_i ( spi_ctrl_data_rx ),
|
||||
.ready_o ( spi_ctrl_data_rx_ready )
|
||||
);
|
||||
|
||||
spi_master_controller u_spictrl
|
||||
(
|
||||
.clk ( HCLK ),
|
||||
.rstn ( HRESETn ),
|
||||
.eot ( s_eot ),
|
||||
.spi_clk_div ( spi_clk_div ),
|
||||
.spi_clk_div_valid ( spi_clk_div_valid ),
|
||||
.spi_status ( spi_ctrl_status ),
|
||||
.spi_addr ( spi_addr ),
|
||||
.spi_addr_len ( spi_addr_len ),
|
||||
.spi_cmd ( spi_cmd ),
|
||||
.spi_cmd_len ( spi_cmd_len ),
|
||||
.spi_data_len ( spi_data_len ),
|
||||
.spi_dummy_rd ( spi_dummy_rd ),
|
||||
.spi_dummy_wr ( spi_dummy_wr ),
|
||||
.spi_swrst ( spi_swrst ),
|
||||
.spi_rd ( spi_rd ),
|
||||
.spi_wr ( spi_wr ),
|
||||
.spi_qrd ( spi_qrd ),
|
||||
.spi_qwr ( spi_qwr ),
|
||||
.spi_csreg ( spi_csreg ),
|
||||
.spi_ctrl_data_tx ( spi_ctrl_data_tx ),
|
||||
.spi_ctrl_data_tx_valid ( spi_ctrl_data_tx_valid ),
|
||||
.spi_ctrl_data_tx_ready ( spi_ctrl_data_tx_ready ),
|
||||
.spi_ctrl_data_rx ( spi_ctrl_data_rx ),
|
||||
.spi_ctrl_data_rx_valid ( spi_ctrl_data_rx_valid ),
|
||||
.spi_ctrl_data_rx_ready ( spi_ctrl_data_rx_ready ),
|
||||
.spi_clk ( spi_clk ),
|
||||
.spi_csn0 ( spi_csn0 ),
|
||||
.spi_csn1 ( spi_csn1 ),
|
||||
.spi_csn2 ( spi_csn2 ),
|
||||
.spi_csn3 ( spi_csn3 ),
|
||||
.spi_mode ( spi_mode ),
|
||||
.spi_sdo0 ( spi_sdo0 ),
|
||||
.spi_sdo1 ( spi_sdo1 ),
|
||||
.spi_sdo2 ( spi_sdo2 ),
|
||||
.spi_sdo3 ( spi_sdo3 ),
|
||||
.spi_sdi0 ( spi_sdi0 ),
|
||||
.spi_sdi1 ( spi_sdi1 ),
|
||||
.spi_sdi2 ( spi_sdi2 ),
|
||||
.spi_sdi3 ( spi_sdi3 )
|
||||
);
|
||||
|
||||
endmodule
|
||||
-179
@@ -1,179 +0,0 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// -- Adaptable modifications made for hbirdv2 SoC. --
|
||||
// Copyright 2020 Nuclei System Technology, Inc.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
`define log2(VALUE) ((VALUE) < ( 1 ) ? 0 : (VALUE) < ( 2 ) ? 1 : (VALUE) < ( 4 ) ? 2 : (VALUE) < ( 8 ) ? 3 : (VALUE) < ( 16 ) ? 4 : (VALUE) < ( 32 ) ? 5 : (VALUE) < ( 64 ) ? 6 : (VALUE) < ( 128 ) ? 7 : (VALUE) < ( 256 ) ? 8 : (VALUE) < ( 512 ) ? 9 : (VALUE) < ( 1024 ) ? 10 : (VALUE) < ( 2048 ) ? 11 : (VALUE) < ( 4096 ) ? 12 : (VALUE) < ( 8192 ) ? 13 : (VALUE) < ( 16384 ) ? 14 : (VALUE) < ( 32768 ) ? 15 : (VALUE) < ( 65536 ) ? 16 : (VALUE) < ( 131072 ) ? 17 : (VALUE) < ( 262144 ) ? 18 : (VALUE) < ( 524288 ) ? 19 : (VALUE) < ( 1048576 ) ? 20 : (VALUE) < ( 1048576 * 2 ) ? 21 : (VALUE) < ( 1048576 * 4 ) ? 22 : (VALUE) < ( 1048576 * 8 ) ? 23 : (VALUE) < ( 1048576 * 16 ) ? 24 : 25)
|
||||
|
||||
`define REG_STATUS 4'b0000 // BASEREG + 0x00
|
||||
`define REG_CLKDIV 4'b0001 // BASEREG + 0x04
|
||||
`define REG_SPICMD 4'b0010 // BASEREG + 0x08
|
||||
`define REG_SPIADR 4'b0011 // BASEREG + 0x0C
|
||||
`define REG_SPILEN 4'b0100 // BASEREG + 0x10
|
||||
`define REG_SPIDUM 4'b0101 // BASEREG + 0x14
|
||||
`define REG_TXFIFO 4'b0110 // BASEREG + 0x18
|
||||
`define REG_RXFIFO 4'b1000 // BASEREG + 0x20
|
||||
`define REG_INTCFG 4'b1001 // BASEREG + 0x24
|
||||
`define REG_INTSTA 4'b1010 // BASEREG + 0x28
|
||||
|
||||
module spi_master_apb_if
|
||||
#(
|
||||
parameter BUFFER_DEPTH = 10,
|
||||
parameter APB_ADDR_WIDTH = 12, //APB slaves are 4KB by default
|
||||
parameter LOG_BUFFER_DEPTH = `log2(BUFFER_DEPTH)
|
||||
)
|
||||
(
|
||||
input wire HCLK,
|
||||
input wire HRESETn,
|
||||
input wire [APB_ADDR_WIDTH - 1:0] PADDR,
|
||||
input wire [31:0] PWDATA,
|
||||
input wire PWRITE,
|
||||
input wire PSEL,
|
||||
input wire PENABLE,
|
||||
output reg [31:0] PRDATA,
|
||||
output wire PREADY,
|
||||
output wire PSLVERR,
|
||||
|
||||
output reg [7:0] spi_clk_div,
|
||||
output reg spi_clk_div_valid,
|
||||
input wire [31:0] spi_status,
|
||||
output reg [31:0] spi_addr,
|
||||
output reg [5:0] spi_addr_len,
|
||||
output reg [31:0] spi_cmd,
|
||||
output reg [5:0] spi_cmd_len,
|
||||
output reg [3:0] spi_csreg,
|
||||
output reg [15:0] spi_data_len,
|
||||
output reg [15:0] spi_dummy_rd,
|
||||
output reg [15:0] spi_dummy_wr,
|
||||
output reg [LOG_BUFFER_DEPTH:0] spi_int_th_tx,
|
||||
output reg [LOG_BUFFER_DEPTH:0] spi_int_th_rx,
|
||||
output reg spi_int_en,
|
||||
input wire [31:0] spi_int_status,
|
||||
output reg spi_swrst,
|
||||
output reg spi_rd,
|
||||
output reg spi_wr,
|
||||
output reg spi_qrd,
|
||||
output reg spi_qwr,
|
||||
output wire [31:0] spi_data_tx,
|
||||
output wire spi_data_tx_valid,
|
||||
input wire spi_data_tx_ready,
|
||||
input wire [31:0] spi_data_rx,
|
||||
input wire spi_data_rx_valid,
|
||||
output wire spi_data_rx_ready
|
||||
);
|
||||
|
||||
wire [3:0] write_address;
|
||||
wire [3:0] read_address;
|
||||
|
||||
assign write_address = PADDR[5:2];
|
||||
assign read_address = PADDR[5:2];
|
||||
|
||||
assign PSLVERR = 1'b0;
|
||||
assign PREADY = 1'b1;
|
||||
|
||||
always @(posedge HCLK or negedge HRESETn) begin
|
||||
if (HRESETn == 1'b0) begin
|
||||
spi_swrst <= 1'b0;
|
||||
spi_rd <= 1'b0;
|
||||
spi_wr <= 1'b0;
|
||||
spi_qrd <= 1'b0;
|
||||
spi_qwr <= 1'b0;
|
||||
spi_clk_div_valid <= 1'b0;
|
||||
spi_clk_div <= 'b0;
|
||||
spi_cmd <= 'b0;
|
||||
spi_addr <= 'b0;
|
||||
spi_cmd_len <= 'b0;
|
||||
spi_addr_len <= 'b0;
|
||||
spi_data_len <= 'b0;
|
||||
spi_dummy_rd <= 'b0;
|
||||
spi_dummy_wr <= 'b0;
|
||||
spi_csreg <= 'b0;
|
||||
spi_int_th_tx <= 'b0;
|
||||
spi_int_th_rx <= 'b0;
|
||||
spi_int_en <= 1'b0;
|
||||
end else if (PSEL && PENABLE && PWRITE) begin
|
||||
spi_swrst <= 1'b0;
|
||||
spi_rd <= 1'b0;
|
||||
spi_wr <= 1'b0;
|
||||
spi_qrd <= 1'b0;
|
||||
spi_qwr <= 1'b0;
|
||||
spi_clk_div_valid <= 1'b0;
|
||||
|
||||
case (write_address)
|
||||
`REG_STATUS: begin
|
||||
spi_rd <= PWDATA[0];
|
||||
spi_wr <= PWDATA[1];
|
||||
spi_qrd <= PWDATA[2];
|
||||
spi_qwr <= PWDATA[3];
|
||||
spi_swrst <= PWDATA[4];
|
||||
spi_csreg <= PWDATA[11:8];
|
||||
end
|
||||
`REG_CLKDIV: begin
|
||||
spi_clk_div <= PWDATA[7:0];
|
||||
spi_clk_div_valid <= 1'b1;
|
||||
end
|
||||
`REG_SPICMD: spi_cmd <= PWDATA;
|
||||
`REG_SPIADR: spi_addr <= PWDATA;
|
||||
`REG_SPILEN: begin
|
||||
spi_cmd_len <= PWDATA[5:0];
|
||||
spi_addr_len <= PWDATA[13:8];
|
||||
spi_data_len[7:0] <= PWDATA[23:16];
|
||||
spi_data_len[15:8] <= PWDATA[31:24];
|
||||
end
|
||||
`REG_SPIDUM: begin
|
||||
spi_dummy_rd[7:0] <= PWDATA[7:0];
|
||||
spi_dummy_rd[15:8] <= PWDATA[15:8];
|
||||
spi_dummy_wr[7:0] <= PWDATA[23:16];
|
||||
spi_dummy_wr[15:8] <= PWDATA[31:24];
|
||||
end
|
||||
`REG_INTCFG: begin
|
||||
spi_int_th_tx <= PWDATA[LOG_BUFFER_DEPTH:0];
|
||||
spi_int_th_rx <= PWDATA[8 + LOG_BUFFER_DEPTH:8];
|
||||
spi_int_en <= PWDATA[31];
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
spi_swrst <= 1'b0;
|
||||
spi_rd <= 1'b0;
|
||||
spi_wr <= 1'b0;
|
||||
spi_qrd <= 1'b0;
|
||||
spi_qwr <= 1'b0;
|
||||
spi_clk_div_valid <= 1'b0;
|
||||
end
|
||||
end // SLAVE_REG_WRITE_PROC
|
||||
|
||||
|
||||
// implement slave model register read mux
|
||||
always @(*) begin
|
||||
case (read_address)
|
||||
`REG_STATUS: PRDATA = spi_status;
|
||||
`REG_CLKDIV: PRDATA = {24'h0, spi_clk_div};
|
||||
`REG_SPICMD: PRDATA = spi_cmd;
|
||||
`REG_SPIADR: PRDATA = spi_addr;
|
||||
`REG_SPILEN: PRDATA = {spi_data_len, 2'b00, spi_addr_len, 2'b00, spi_cmd_len};
|
||||
`REG_SPIDUM: PRDATA = {spi_dummy_wr, spi_dummy_rd};
|
||||
`REG_RXFIFO: PRDATA = spi_data_rx;
|
||||
`REG_INTCFG: begin
|
||||
PRDATA = 'b0;
|
||||
PRDATA[LOG_BUFFER_DEPTH:0] = spi_int_th_tx;
|
||||
PRDATA[8 + LOG_BUFFER_DEPTH:8] = spi_int_th_rx;
|
||||
PRDATA[31] = spi_int_en;
|
||||
end
|
||||
`REG_INTSTA: PRDATA = spi_int_status;
|
||||
default: PRDATA = 'b0;
|
||||
endcase
|
||||
end // SLAVE_REG_READ_PROC
|
||||
|
||||
assign spi_data_tx = PWDATA;
|
||||
assign spi_data_tx_valid = ((PSEL & PENABLE) & PWRITE) & (write_address == `REG_TXFIFO);
|
||||
assign spi_data_rx_ready = ((PSEL & PENABLE) & ~PWRITE) & (read_address == `REG_RXFIFO);
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// -- Adaptable modifications made for hbirdv2 SoC. --
|
||||
// Copyright 2020 Nuclei System Technology, Inc.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
module spi_master_clkgen (
|
||||
input wire clk,
|
||||
input wire rstn,
|
||||
input wire en,
|
||||
input wire [7:0] clk_div,
|
||||
input wire clk_div_valid,
|
||||
output reg spi_clk,
|
||||
output reg spi_fall,
|
||||
output reg spi_rise
|
||||
);
|
||||
|
||||
reg [7:0] counter_trgt;
|
||||
reg [7:0] counter_trgt_next;
|
||||
reg [7:0] counter;
|
||||
reg [7:0] counter_next;
|
||||
|
||||
reg spi_clk_next;
|
||||
reg running;
|
||||
|
||||
always @(*) begin
|
||||
spi_rise = 1'b0;
|
||||
spi_fall = 1'b0;
|
||||
|
||||
if (clk_div_valid)
|
||||
counter_trgt_next = clk_div;
|
||||
else
|
||||
counter_trgt_next = counter_trgt;
|
||||
|
||||
if (counter == counter_trgt) begin
|
||||
counter_next = 0;
|
||||
spi_clk_next = ~spi_clk;
|
||||
|
||||
if (spi_clk == 1'b0)
|
||||
spi_rise = running;
|
||||
else
|
||||
spi_fall = running;
|
||||
|
||||
end else begin
|
||||
counter_next = counter + 1;
|
||||
spi_clk_next = spi_clk;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge rstn) begin
|
||||
if (rstn == 1'b0) begin
|
||||
counter_trgt <= 'h0;
|
||||
counter <= 'h0;
|
||||
spi_clk <= 1'b0;
|
||||
running <= 1'b0;
|
||||
end else begin
|
||||
counter_trgt <= counter_trgt_next;
|
||||
|
||||
if (!((spi_clk == 1'b0) && ~en)) begin
|
||||
running <= 1'b1;
|
||||
spi_clk <= spi_clk_next;
|
||||
counter <= counter_next;
|
||||
end else
|
||||
running <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -1,497 +0,0 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// -- Adaptable modifications made for hbirdv2 SoC. --
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
`define SPI_STD 2'b00
|
||||
`define SPI_QUAD_TX 2'b01
|
||||
`define SPI_QUAD_RX 2'b10
|
||||
|
||||
module spi_master_controller (
|
||||
input wire clk,
|
||||
input wire rstn,
|
||||
output reg eot,
|
||||
input wire [7:0] spi_clk_div,
|
||||
input wire spi_clk_div_valid,
|
||||
output reg [6:0] spi_status,
|
||||
input wire [31:0] spi_addr,
|
||||
input wire [5:0] spi_addr_len,
|
||||
input wire [31:0] spi_cmd,
|
||||
input wire [5:0] spi_cmd_len,
|
||||
input wire [15:0] spi_data_len,
|
||||
input wire [15:0] spi_dummy_rd,
|
||||
input wire [15:0] spi_dummy_wr,
|
||||
input wire [3:0] spi_csreg,
|
||||
input wire spi_swrst, //FIXME Not used at all
|
||||
input wire spi_rd,
|
||||
input wire spi_wr,
|
||||
input wire spi_qrd,
|
||||
input wire spi_qwr,
|
||||
input wire [31:0] spi_ctrl_data_tx,
|
||||
input wire spi_ctrl_data_tx_valid,
|
||||
output reg spi_ctrl_data_tx_ready,
|
||||
output wire [31:0] spi_ctrl_data_rx,
|
||||
output wire spi_ctrl_data_rx_valid,
|
||||
input wire spi_ctrl_data_rx_ready,
|
||||
output wire spi_clk,
|
||||
output wire spi_csn0,
|
||||
output wire spi_csn1,
|
||||
output wire spi_csn2,
|
||||
output wire spi_csn3,
|
||||
output reg [1:0] spi_mode,
|
||||
output wire spi_sdo0,
|
||||
output wire spi_sdo1,
|
||||
output wire spi_sdo2,
|
||||
output wire spi_sdo3,
|
||||
input wire spi_sdi0,
|
||||
input wire spi_sdi1,
|
||||
input wire spi_sdi2,
|
||||
input wire spi_sdi3
|
||||
);
|
||||
|
||||
localparam [2:0] DATA_NULL = 0;
|
||||
localparam [2:0] DATA_EMPTY = 1;
|
||||
localparam [2:0] DATA_CMD = 2;
|
||||
localparam [2:0] DATA_ADDR = 3;
|
||||
localparam [2:0] DATA_FIFO = 4;
|
||||
|
||||
localparam [4:0] IDLE = 0;
|
||||
localparam [4:0] CMD = 1;
|
||||
localparam [4:0] ADDR = 2;
|
||||
localparam [4:0] MODE = 3;
|
||||
localparam [4:0] DUMMY = 4;
|
||||
localparam [4:0] DATA_TX = 5;
|
||||
localparam [4:0] DATA_RX = 6;
|
||||
localparam [4:0] WAIT_EDGE = 7;
|
||||
|
||||
|
||||
wire spi_rise;
|
||||
wire spi_fall;
|
||||
|
||||
reg spi_clock_en;
|
||||
|
||||
reg spi_en_tx;
|
||||
reg spi_en_rx;
|
||||
|
||||
reg [15:0] counter_tx;
|
||||
reg counter_tx_valid;
|
||||
reg [15:0] counter_rx;
|
||||
reg counter_rx_valid;
|
||||
|
||||
reg [31:0] data_to_tx;
|
||||
reg data_to_tx_valid;
|
||||
wire data_to_tx_ready;
|
||||
|
||||
wire en_quad;
|
||||
reg en_quad_int;
|
||||
reg do_tx; //FIXME NOT USED at all!!
|
||||
reg do_rx;
|
||||
|
||||
wire tx_done;
|
||||
wire rx_done;
|
||||
|
||||
reg [1:0] s_spi_mode;
|
||||
|
||||
reg ctrl_data_valid;
|
||||
|
||||
reg spi_cs;
|
||||
|
||||
wire tx_clk_en;
|
||||
wire rx_clk_en;
|
||||
|
||||
reg [2:0] ctrl_data_mux;
|
||||
reg [4:0] state;
|
||||
reg [4:0] state_next;
|
||||
|
||||
|
||||
assign en_quad = (spi_qrd | spi_qwr) | en_quad_int;
|
||||
|
||||
spi_master_clkgen u_clkgen
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rstn ( rstn ),
|
||||
.en ( spi_clock_en ),
|
||||
.clk_div ( spi_clk_div ),
|
||||
.clk_div_valid ( spi_clk_div_valid ),
|
||||
.spi_clk ( spi_clk ),
|
||||
.spi_fall ( spi_fall ),
|
||||
.spi_rise ( spi_rise )
|
||||
);
|
||||
|
||||
spi_master_tx u_txreg
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rstn ( rstn ),
|
||||
.en ( spi_en_tx ),
|
||||
.tx_edge ( spi_fall ),
|
||||
.tx_done ( tx_done ),
|
||||
.sdo0 ( spi_sdo0 ),
|
||||
.sdo1 ( spi_sdo1 ),
|
||||
.sdo2 ( spi_sdo2 ),
|
||||
.sdo3 ( spi_sdo3 ),
|
||||
.en_quad_in ( en_quad ),
|
||||
.counter_in ( counter_tx ),
|
||||
.counter_in_upd ( counter_tx_valid ),
|
||||
.data ( data_to_tx ),
|
||||
.data_valid ( data_to_tx_valid ),
|
||||
.data_ready ( data_to_tx_ready ),
|
||||
.clk_en_o ( tx_clk_en )
|
||||
);
|
||||
|
||||
spi_master_rx u_rxreg
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rstn ( rstn ),
|
||||
.en ( spi_en_rx ),
|
||||
.rx_edge ( spi_rise ),
|
||||
.rx_done ( rx_done ),
|
||||
.sdi0 ( spi_sdi0 ),
|
||||
.sdi1 ( spi_sdi1 ),
|
||||
.sdi2 ( spi_sdi2 ),
|
||||
.sdi3 ( spi_sdi3 ),
|
||||
.en_quad_in ( en_quad ),
|
||||
.counter_in ( counter_rx ),
|
||||
.counter_in_upd ( counter_rx_valid ),
|
||||
.data ( spi_ctrl_data_rx ),
|
||||
.data_valid ( spi_ctrl_data_rx_valid ),
|
||||
.data_ready ( spi_ctrl_data_rx_ready ),
|
||||
.clk_en_o ( rx_clk_en )
|
||||
);
|
||||
|
||||
always @(*) begin
|
||||
data_to_tx = 'h0;
|
||||
data_to_tx_valid = 1'b0;
|
||||
spi_ctrl_data_tx_ready = 1'b0;
|
||||
|
||||
case (ctrl_data_mux)
|
||||
DATA_NULL: begin
|
||||
data_to_tx = 'b0;
|
||||
data_to_tx_valid = 1'b0;
|
||||
spi_ctrl_data_tx_ready = 1'b0;
|
||||
end
|
||||
DATA_EMPTY: begin
|
||||
data_to_tx = 'b0;
|
||||
data_to_tx_valid = 1'b1;
|
||||
end
|
||||
DATA_CMD: begin
|
||||
data_to_tx = spi_cmd;
|
||||
data_to_tx_valid = ctrl_data_valid;
|
||||
spi_ctrl_data_tx_ready = 1'b0;
|
||||
end
|
||||
DATA_ADDR: begin
|
||||
data_to_tx = spi_addr;
|
||||
data_to_tx_valid = ctrl_data_valid;
|
||||
spi_ctrl_data_tx_ready = 1'b0;
|
||||
end
|
||||
DATA_FIFO: begin
|
||||
data_to_tx = spi_ctrl_data_tx;
|
||||
data_to_tx_valid = spi_ctrl_data_tx_valid;
|
||||
spi_ctrl_data_tx_ready = data_to_tx_ready;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
spi_cs = 1'b1;
|
||||
spi_clock_en = 1'b0;
|
||||
counter_tx = 'b0;
|
||||
counter_tx_valid = 1'b0;
|
||||
counter_rx = 'b0;
|
||||
counter_rx_valid = 1'b0;
|
||||
state_next = state;
|
||||
ctrl_data_mux = DATA_NULL;
|
||||
ctrl_data_valid = 1'b0;
|
||||
spi_en_rx = 1'b0;
|
||||
spi_en_tx = 1'b0;
|
||||
spi_status = 'b0;
|
||||
s_spi_mode = `SPI_QUAD_RX;
|
||||
eot = 1'b0;
|
||||
case (state)
|
||||
IDLE: begin
|
||||
spi_status[0] = 1'b1;
|
||||
s_spi_mode = `SPI_QUAD_RX;
|
||||
|
||||
if (spi_rd || spi_wr || spi_qrd || spi_qwr) begin
|
||||
spi_cs = 1'b0;
|
||||
spi_clock_en = 1'b1;
|
||||
|
||||
if (spi_cmd_len != 0) begin
|
||||
s_spi_mode = (spi_qrd | spi_qwr) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
counter_tx = {8'h00, spi_cmd_len};
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_CMD;
|
||||
ctrl_data_valid = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = CMD;
|
||||
end else if (spi_addr_len != 0) begin
|
||||
s_spi_mode = (spi_qrd | spi_qwr) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
counter_tx = {8'h00, spi_addr_len};
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_ADDR;
|
||||
ctrl_data_valid = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = ADDR;
|
||||
end else if (spi_data_len != 0)
|
||||
if (spi_rd || spi_qrd) begin
|
||||
s_spi_mode = (spi_qrd) ? `SPI_QUAD_RX : `SPI_STD;
|
||||
|
||||
if (spi_dummy_rd != 0) begin
|
||||
counter_tx = (en_quad) ? {spi_dummy_rd[13:0], 2'b00} : spi_dummy_rd;
|
||||
counter_tx_valid = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
ctrl_data_mux = DATA_EMPTY;
|
||||
state_next = DUMMY;
|
||||
end else begin
|
||||
counter_rx = spi_data_len;
|
||||
counter_rx_valid = 1'b1;
|
||||
spi_en_rx = 1'b1;
|
||||
state_next = DATA_RX;
|
||||
end
|
||||
end else begin
|
||||
s_spi_mode = (spi_qwr) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
|
||||
if (spi_dummy_wr != 0) begin
|
||||
counter_tx = (en_quad) ? {spi_dummy_wr[13:0], 2'b00} : spi_dummy_wr;
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_EMPTY;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = DUMMY;
|
||||
end else begin
|
||||
counter_tx = spi_data_len;
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_FIFO;
|
||||
ctrl_data_valid = 1'b0;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = DATA_TX;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
spi_cs = 1'b1;
|
||||
state_next = IDLE;
|
||||
end
|
||||
end
|
||||
CMD: begin
|
||||
spi_status[1] = 1'b1;
|
||||
spi_cs = 1'b0;
|
||||
spi_clock_en = 1'b1;
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
|
||||
if (tx_done) begin
|
||||
if (spi_addr_len != 0) begin
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
counter_tx = {8'h00, spi_addr_len};
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_ADDR;
|
||||
ctrl_data_valid = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = ADDR;
|
||||
end else if (spi_data_len != 0) begin
|
||||
if (do_rx) begin
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_RX : `SPI_STD;
|
||||
if (spi_dummy_rd != 0) begin
|
||||
counter_tx = (en_quad) ? {spi_dummy_rd[13:0], 2'b00} : spi_dummy_rd;
|
||||
counter_tx_valid = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
ctrl_data_mux = DATA_EMPTY;
|
||||
state_next = DUMMY;
|
||||
end else begin
|
||||
counter_rx = spi_data_len;
|
||||
counter_rx_valid = 1'b1;
|
||||
spi_en_rx = 1'b1;
|
||||
state_next = DATA_RX;
|
||||
end
|
||||
end else begin
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
if (spi_dummy_wr != 0) begin
|
||||
counter_tx = (en_quad) ? {spi_dummy_wr[13:0], 2'b00} : spi_dummy_wr;
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_EMPTY;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = DUMMY;
|
||||
end else begin
|
||||
counter_tx = spi_data_len;
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_FIFO;
|
||||
ctrl_data_valid = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = DATA_TX;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
state_next = IDLE;
|
||||
end
|
||||
end else begin
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = CMD;
|
||||
end
|
||||
end
|
||||
ADDR: begin
|
||||
spi_en_tx = 1'b1;
|
||||
spi_status[2] = 1'b1;
|
||||
spi_cs = 1'b0;
|
||||
spi_clock_en = 1'b1;
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
if (tx_done) begin
|
||||
if (spi_data_len != 0) begin
|
||||
if (do_rx) begin
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_RX : `SPI_STD;
|
||||
if (spi_dummy_rd != 0) begin
|
||||
counter_tx = (en_quad) ? {spi_dummy_rd[13:0], 2'b00} : spi_dummy_rd;
|
||||
counter_tx_valid = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
ctrl_data_mux = DATA_EMPTY;
|
||||
state_next = DUMMY;
|
||||
end else begin
|
||||
counter_rx = spi_data_len;
|
||||
counter_rx_valid = 1'b1;
|
||||
spi_en_rx = 1'b1;
|
||||
state_next = DATA_RX;
|
||||
end
|
||||
end else begin
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
spi_en_tx = 1'b1;
|
||||
|
||||
if (spi_dummy_wr != 0) begin
|
||||
counter_tx = (en_quad) ? {spi_dummy_wr[13:0], 2'b00} : spi_dummy_wr;
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_EMPTY;
|
||||
state_next = DUMMY;
|
||||
end else begin
|
||||
counter_tx = spi_data_len;
|
||||
counter_tx_valid = 1'b1;
|
||||
ctrl_data_mux = DATA_FIFO;
|
||||
ctrl_data_valid = 1'b1;
|
||||
state_next = DATA_TX;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
state_next = IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
MODE: begin
|
||||
spi_status[3] = 1'b1;
|
||||
spi_cs = 1'b0;
|
||||
spi_clock_en = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
end
|
||||
DUMMY: begin
|
||||
spi_en_tx = 1'b1;
|
||||
spi_status[4] = 1'b1;
|
||||
spi_cs = 1'b0;
|
||||
spi_clock_en = 1'b1;
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_RX : `SPI_STD;
|
||||
|
||||
if (tx_done) begin
|
||||
if (spi_data_len != 0) begin
|
||||
if (do_rx) begin
|
||||
counter_rx = spi_data_len;
|
||||
counter_rx_valid = 1'b1;
|
||||
spi_en_rx = 1'b1;
|
||||
state_next = DATA_RX;
|
||||
end else begin
|
||||
counter_tx = spi_data_len;
|
||||
counter_tx_valid = 1'b1;
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
spi_clock_en = tx_clk_en;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = DATA_TX;
|
||||
end
|
||||
end else begin
|
||||
eot = 1'b1;
|
||||
state_next = IDLE;
|
||||
end
|
||||
end else begin
|
||||
ctrl_data_mux = DATA_EMPTY;
|
||||
spi_en_tx = 1'b1;
|
||||
state_next = DUMMY;
|
||||
end
|
||||
end
|
||||
DATA_TX: begin
|
||||
spi_status[5] = 1'b1;
|
||||
spi_cs = 1'b0;
|
||||
spi_clock_en = tx_clk_en;
|
||||
ctrl_data_mux = DATA_FIFO;
|
||||
ctrl_data_valid = 1'b1;
|
||||
spi_en_tx = 1'b1;
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_TX : `SPI_STD;
|
||||
|
||||
if (tx_done) begin
|
||||
eot = 1'b1;
|
||||
state_next = IDLE;
|
||||
spi_clock_en = 1'b0;
|
||||
end else begin
|
||||
state_next = DATA_TX;
|
||||
end
|
||||
end
|
||||
DATA_RX: begin
|
||||
spi_status[6] = 1'b1;
|
||||
spi_cs = 1'b0;
|
||||
spi_clock_en = rx_clk_en;
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_RX : `SPI_STD;
|
||||
|
||||
if (rx_done) begin
|
||||
state_next = WAIT_EDGE;
|
||||
end else begin
|
||||
spi_en_rx = 1'b1;
|
||||
state_next = DATA_RX;
|
||||
end
|
||||
end
|
||||
WAIT_EDGE: begin
|
||||
spi_status[6] = 1'b1;
|
||||
spi_cs = 1'b0;
|
||||
spi_clock_en = 1'b0;
|
||||
s_spi_mode = (en_quad) ? `SPI_QUAD_RX : `SPI_STD;
|
||||
|
||||
if (spi_fall) begin
|
||||
eot = 1'b1;
|
||||
state_next = IDLE;
|
||||
end else begin
|
||||
state_next = WAIT_EDGE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk or negedge rstn) begin
|
||||
if (rstn == 1'b0) begin
|
||||
state <= IDLE;
|
||||
en_quad_int <= 1'b0;
|
||||
do_rx <= 1'b0;
|
||||
do_tx <= 1'b0;
|
||||
spi_mode <= `SPI_QUAD_RX;
|
||||
end else begin
|
||||
state <= state_next;
|
||||
spi_mode <= s_spi_mode;
|
||||
|
||||
if (spi_qrd || spi_qwr)
|
||||
en_quad_int <= 1'b1;
|
||||
else if (state_next == IDLE)
|
||||
en_quad_int <= 1'b0;
|
||||
|
||||
if (spi_rd || spi_qrd) begin
|
||||
do_rx <= 1'b1;
|
||||
do_tx <= 1'b0;
|
||||
end else if (spi_wr || spi_qwr) begin
|
||||
do_rx <= 1'b0;
|
||||
do_tx <= 1'b1;
|
||||
end else if (state_next == IDLE) begin
|
||||
do_rx <= 1'b0;
|
||||
do_tx <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign spi_csn0 = ~spi_csreg[0] | spi_cs;
|
||||
assign spi_csn1 = ~spi_csreg[1] | spi_cs;
|
||||
assign spi_csn2 = ~spi_csreg[2] | spi_cs;
|
||||
assign spi_csn3 = ~spi_csreg[3] | spi_cs;
|
||||
|
||||
endmodule
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// -- Adaptable modifications made for hbirdv2 SoC. --
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
`define log2(VALUE) ((VALUE) < ( 1 ) ? 0 : (VALUE) < ( 2 ) ? 1 : (VALUE) < ( 4 ) ? 2 : (VALUE) < ( 8 ) ? 3 : (VALUE) < ( 16 ) ? 4 : (VALUE) < ( 32 ) ? 5 : (VALUE) < ( 64 ) ? 6 : (VALUE) < ( 128 ) ? 7 : (VALUE) < ( 256 ) ? 8 : (VALUE) < ( 512 ) ? 9 : (VALUE) < ( 1024 ) ? 10 : (VALUE) < ( 2048 ) ? 11 : (VALUE) < ( 4096 ) ? 12 : (VALUE) < ( 8192 ) ? 13 : (VALUE) < ( 16384 ) ? 14 : (VALUE) < ( 32768 ) ? 15 : (VALUE) < ( 65536 ) ? 16 : (VALUE) < ( 131072 ) ? 17 : (VALUE) < ( 262144 ) ? 18 : (VALUE) < ( 524288 ) ? 19 : (VALUE) < ( 1048576 ) ? 20 : (VALUE) < ( 1048576 * 2 ) ? 21 : (VALUE) < ( 1048576 * 4 ) ? 22 : (VALUE) < ( 1048576 * 8 ) ? 23 : (VALUE) < ( 1048576 * 16 ) ? 24 : 25)
|
||||
|
||||
module spi_master_fifo
|
||||
#(
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter BUFFER_DEPTH = 2,
|
||||
parameter LOG_BUFFER_DEPTH = `log2(BUFFER_DEPTH)
|
||||
)
|
||||
(
|
||||
input wire clk_i,
|
||||
input wire rst_ni,
|
||||
input wire clr_i,
|
||||
output wire [LOG_BUFFER_DEPTH:0] elements_o,
|
||||
output wire [DATA_WIDTH - 1:0] data_o,
|
||||
output wire valid_o,
|
||||
input wire ready_i,
|
||||
input wire valid_i,
|
||||
input wire [DATA_WIDTH - 1:0] data_i,
|
||||
output wire ready_o
|
||||
);
|
||||
|
||||
// Internal data structures
|
||||
reg [LOG_BUFFER_DEPTH - 1:0] pointer_in; // location to which we last wrote
|
||||
reg [LOG_BUFFER_DEPTH - 1:0] pointer_out; // location from which we last sent
|
||||
reg [LOG_BUFFER_DEPTH:0] elements; // number of elements in the buffer
|
||||
reg [DATA_WIDTH - 1:0] buffer [BUFFER_DEPTH - 1:0];
|
||||
|
||||
|
||||
wire full;
|
||||
integer loop1;
|
||||
|
||||
assign full = (elements == BUFFER_DEPTH);
|
||||
assign elements_o = elements;
|
||||
|
||||
always @(posedge clk_i or negedge rst_ni) begin : elements_sequential
|
||||
if (rst_ni == 1'b0)
|
||||
elements <= 0;
|
||||
else if (clr_i)
|
||||
elements <= 0;
|
||||
// ------------------
|
||||
// Are we filling up?
|
||||
// ------------------
|
||||
// One out, none in
|
||||
else if ((ready_i && valid_o) && (!valid_i || full))
|
||||
elements <= elements - 1;
|
||||
// None out, one in
|
||||
else if (((!valid_o || !ready_i) && valid_i) && !full)
|
||||
elements <= elements + 1;
|
||||
// Else, either one out and one in, or none out and none in - stays unchanged
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk_i or negedge rst_ni) begin : buffers_sequential
|
||||
if (rst_ni == 1'b0) begin
|
||||
for (loop1 = 0; loop1 < BUFFER_DEPTH; loop1 = loop1 + 1)
|
||||
buffer[loop1] <= 0;
|
||||
end
|
||||
else if (valid_i && !full)
|
||||
// Update the memory
|
||||
buffer[pointer_in] <= data_i;
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk_i or negedge rst_ni) begin : sequential
|
||||
if (rst_ni == 1'b0) begin
|
||||
pointer_out <= 0;
|
||||
pointer_in <= 0;
|
||||
end else if (clr_i) begin
|
||||
pointer_out <= 0;
|
||||
pointer_in <= 0;
|
||||
end else begin
|
||||
// ------------------------------------
|
||||
// Check what to do with the input side
|
||||
// ------------------------------------
|
||||
// We have some input, increase by 1 the input pointer
|
||||
if (valid_i && !full) begin
|
||||
if (pointer_in == $unsigned(BUFFER_DEPTH - 1))
|
||||
pointer_in <= 0;
|
||||
else
|
||||
pointer_in <= pointer_in + 1;
|
||||
end
|
||||
// Else we don't have any input, the input pointer stays the same
|
||||
|
||||
// -------------------------------------
|
||||
// Check what to do with the output side
|
||||
// -------------------------------------
|
||||
// We had pushed one flit out, we can try to go for the next one
|
||||
if (ready_i && valid_o) begin
|
||||
if (pointer_out == $unsigned(BUFFER_DEPTH - 1))
|
||||
pointer_out <= 0;
|
||||
else
|
||||
pointer_out <= pointer_out + 1;
|
||||
end
|
||||
// Else stay on the same output location
|
||||
end
|
||||
end
|
||||
|
||||
// Update output ports
|
||||
assign data_o = buffer[pointer_out];
|
||||
assign valid_o = (elements != 0);
|
||||
assign ready_o = ~full;
|
||||
|
||||
endmodule
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// -- Adaptable modifications made for hbirdv2 SoC. --
|
||||
// Copyright 2020 Nuclei System Technology, Inc.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
module spi_master_rx (
|
||||
input wire clk,
|
||||
input wire rstn,
|
||||
input wire en,
|
||||
input wire rx_edge,
|
||||
output wire rx_done,
|
||||
input wire sdi0,
|
||||
input wire sdi1,
|
||||
input wire sdi2,
|
||||
input wire sdi3,
|
||||
input wire en_quad_in,
|
||||
input wire [15:0] counter_in,
|
||||
input wire counter_in_upd,
|
||||
output wire [31:0] data,
|
||||
input wire data_ready,
|
||||
output reg data_valid,
|
||||
output reg clk_en_o
|
||||
);
|
||||
localparam [1:0] IDLE = 0;
|
||||
localparam [1:0] RECEIVE = 1;
|
||||
localparam [1:0] WAIT_FIFO = 2;
|
||||
localparam [1:0] WAIT_FIFO_DONE = 3;
|
||||
|
||||
reg [31:0] data_int;
|
||||
reg [31:0] data_int_next;
|
||||
reg [15:0] counter;
|
||||
reg [15:0] counter_trgt;
|
||||
reg [15:0] counter_next;
|
||||
reg [15:0] counter_trgt_next;
|
||||
wire done;
|
||||
wire reg_done;
|
||||
|
||||
reg [1:0] rx_CS;
|
||||
reg [1:0] rx_NS;
|
||||
|
||||
assign reg_done = (!en_quad_in && (counter[4:0] == 5'b11111)) || (en_quad_in && (counter[2:0] == 3'b111));
|
||||
assign data = data_int_next;
|
||||
assign rx_done = done;
|
||||
|
||||
always @(*) begin
|
||||
if (counter_in_upd)
|
||||
counter_trgt_next = (en_quad_in ? {2'b00, counter_in[15:2]} : counter_in);
|
||||
else
|
||||
counter_trgt_next = counter_trgt;
|
||||
end
|
||||
|
||||
assign done = (counter == (counter_trgt - 1)) && rx_edge;
|
||||
|
||||
always @(*) begin
|
||||
rx_NS = rx_CS;
|
||||
clk_en_o = 1'b0;
|
||||
data_int_next = data_int;
|
||||
data_valid = 1'b0;
|
||||
counter_next = counter;
|
||||
|
||||
case (rx_CS)
|
||||
IDLE: begin
|
||||
clk_en_o = 1'b0;
|
||||
|
||||
// check first if there is available space instead of later
|
||||
if (en) rx_NS = RECEIVE;
|
||||
end
|
||||
RECEIVE: begin
|
||||
clk_en_o = 1'b1;
|
||||
|
||||
if (rx_edge) begin
|
||||
counter_next = counter + 1;
|
||||
|
||||
if (en_quad_in)
|
||||
data_int_next = {data_int[27:0], sdi3, sdi2, sdi1, sdi0};
|
||||
else
|
||||
data_int_next = {data_int[30:0], sdi1};
|
||||
|
||||
if (rx_done) begin
|
||||
counter_next = 0;
|
||||
data_valid = 1'b1;
|
||||
|
||||
if (data_ready)
|
||||
rx_NS = IDLE;
|
||||
else
|
||||
rx_NS = WAIT_FIFO_DONE;
|
||||
|
||||
end else if (reg_done) begin
|
||||
data_valid = 1'b1;
|
||||
|
||||
if (~data_ready) begin
|
||||
// no space in the FIFO, wait for free space
|
||||
clk_en_o = 1'b0;
|
||||
rx_NS = WAIT_FIFO;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
WAIT_FIFO_DONE: begin
|
||||
data_valid = 1'b1;
|
||||
if (data_ready) rx_NS = IDLE;
|
||||
end
|
||||
WAIT_FIFO: begin
|
||||
data_valid = 1'b1;
|
||||
if (data_ready) rx_NS = RECEIVE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk or negedge rstn) begin
|
||||
if (rstn == 0) begin
|
||||
counter <= 0;
|
||||
counter_trgt <= 'h8;
|
||||
data_int <= 'b0;
|
||||
rx_CS <= IDLE;
|
||||
end else begin
|
||||
counter <= counter_next;
|
||||
counter_trgt <= counter_trgt_next;
|
||||
data_int <= data_int_next;
|
||||
rx_CS <= rx_NS;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// -- Adaptable modifications made for hbirdv2 SoC. --
|
||||
// Copyright 2020 Nuclei System Technology, Inc.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
module spi_master_tx (
|
||||
input wire clk,
|
||||
input wire rstn,
|
||||
input wire en,
|
||||
input wire tx_edge,
|
||||
output wire tx_done,
|
||||
output wire sdo0,
|
||||
output wire sdo1,
|
||||
output wire sdo2,
|
||||
output wire sdo3,
|
||||
input wire en_quad_in,
|
||||
input wire [15:0] counter_in,
|
||||
input wire counter_in_upd,
|
||||
input wire [31:0] data,
|
||||
input wire data_valid,
|
||||
output reg data_ready,
|
||||
output reg clk_en_o
|
||||
);
|
||||
localparam [0:0] IDLE = 0;
|
||||
localparam [0:0] TRANSMIT = 1;
|
||||
|
||||
reg [31:0] data_int;
|
||||
reg [31:0] data_int_next;
|
||||
reg [15:0] counter;
|
||||
reg [15:0] counter_trgt;
|
||||
reg [15:0] counter_next;
|
||||
reg [15:0] counter_trgt_next;
|
||||
|
||||
wire done;
|
||||
wire reg_done;
|
||||
|
||||
reg [0:0] tx_CS;
|
||||
reg [0:0] tx_NS;
|
||||
|
||||
assign sdo0 = (en_quad_in ? data_int[28] : data_int[31]);
|
||||
assign sdo1 = data_int[29];
|
||||
assign sdo2 = data_int[30];
|
||||
assign sdo3 = data_int[31];
|
||||
|
||||
assign tx_done = done;
|
||||
assign reg_done = (!en_quad_in && (counter[4:0] == 5'b11111)) || (en_quad_in && (counter[2:0] == 3'b111));
|
||||
|
||||
always @(*) begin
|
||||
if (counter_in_upd)
|
||||
counter_trgt_next = (en_quad_in ? {2'b00, counter_in[15:2]} : counter_in);
|
||||
else
|
||||
counter_trgt_next = counter_trgt;
|
||||
end
|
||||
|
||||
assign done = (counter == (counter_trgt - 1)) && tx_edge;
|
||||
|
||||
always @(*) begin
|
||||
tx_NS = tx_CS;
|
||||
clk_en_o = 1'b0;
|
||||
data_int_next = data_int;
|
||||
data_ready = 1'b0;
|
||||
counter_next = counter;
|
||||
|
||||
case (tx_CS)
|
||||
IDLE: begin
|
||||
clk_en_o = 1'b0;
|
||||
|
||||
if (en && data_valid) begin
|
||||
data_int_next = data;
|
||||
data_ready = 1'b1;
|
||||
tx_NS = TRANSMIT;
|
||||
end
|
||||
end
|
||||
TRANSMIT: begin
|
||||
clk_en_o = 1'b1;
|
||||
|
||||
if (tx_edge) begin
|
||||
counter_next = counter + 1;
|
||||
data_int_next = (en_quad_in ? {data_int[27:0], 4'b0000} : {data_int[30:0], 1'b0});
|
||||
|
||||
if (tx_done) begin
|
||||
counter_next = 0;
|
||||
|
||||
if (en && data_valid) begin
|
||||
data_int_next = data;
|
||||
data_ready = 1'b1;
|
||||
tx_NS = TRANSMIT;
|
||||
end else begin
|
||||
clk_en_o = 1'b0;
|
||||
tx_NS = IDLE;
|
||||
end
|
||||
end else if (reg_done) begin
|
||||
if (data_valid) begin
|
||||
data_int_next = data;
|
||||
data_ready = 1'b1;
|
||||
end else begin
|
||||
clk_en_o = 1'b0;
|
||||
tx_NS = IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk or negedge rstn) begin
|
||||
if (~rstn) begin
|
||||
counter <= 0;
|
||||
counter_trgt <= 'h8;
|
||||
data_int <= 'h0;
|
||||
tx_CS <= IDLE;
|
||||
end else begin
|
||||
counter <= counter_next;
|
||||
counter_trgt <= counter_trgt_next;
|
||||
data_int <= data_int_next;
|
||||
tx_CS <= tx_NS;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -6,9 +6,9 @@ create_clock -period $clk_period [get_ports extclk_i_pad]
|
||||
|
||||
create_generated_clock -name CLK_sys_peri -divide_by 1 -source u_xtal_io_pad.u_PXWE1W/XC [get_pins u_sys_mux.u_LVT_CKMUX2HDV4/Z]
|
||||
create_generated_clock -name CLK_flash_clk_o -divide_by 1 -source u_retrosoc.u_spimemio.xfer.flash_clk_reg/Q [get_ports flash_clk_o_pad]
|
||||
# create_generated_clock -name CLK_cust_qspi_spi_clk_o -divide_by 1 -source u_retrosoc.u_axil_ip_wrapper.u_apb_spi_master.u_spictrl.u_clkgen.spi_clk_reg/Q [get_ports cust_qspi_spi_clk_o_pad]
|
||||
# create_generated_clock -name CLK_cust_psram_sclk_o -divide_by 2 -source u_retrosoc.u_psram.sclk_reg/Q [get_ports cust_psram_sclk_o_pad]
|
||||
# create_generated_clock -name CLK_cust_spfs_clk_o -divide_by 1 -source u_retrosoc.u_axil_ip_wrapper.u_spi_flash.u0_spi_top.clgen.clk_out_reg/Q [get_ports cust_spfs_clk_o_pad]
|
||||
create_generated_clock -name CLK_cust_qspi_spi_clk_o -divide_by 1 -source u_retrosoc.u_axil_ip_wrapper.u_apb_spi_master.u_spictrl.u_clkgen.spi_clk_reg/Q [get_ports cust_qspi_spi_clk_o_pad]
|
||||
create_generated_clock -name CLK_cust_psram_sclk_o -divide_by 2 -source u_retrosoc.u_psram.sclk_reg/Q [get_ports cust_psram_sclk_o_pad]
|
||||
create_generated_clock -name CLK_cust_spfs_clk_o -divide_by 1 -source u_retrosoc.u_axil_ip_wrapper.u_spi_flash.u0_spi_top.clgen.clk_out_reg/Q [get_ports cust_spfs_clk_o_pad]
|
||||
|
||||
set_false_path -from [get_cells s_ext_rst_n_sync_reg]
|
||||
|
||||
|
||||
Reference in new issue
Block a user