qspim is not link to git repo
diff --git a/.gitmodules b/.gitmodules index 03d7cd9..dcb776f 100644 --- a/.gitmodules +++ b/.gitmodules
@@ -1,3 +1,6 @@ -[submodule "caravel1"] +[submodule "caravel"] path = caravel url = https://github.com/efabless/caravel-lite.git +[submodule "verilog/rtl/qspim"] + path = verilog/rtl/qspim + url = https://github.com/dineshannayya/qspim.git
diff --git a/verilog/rtl/qspim b/verilog/rtl/qspim new file mode 160000 index 0000000..7fd05d1 --- /dev/null +++ b/verilog/rtl/qspim
@@ -0,0 +1 @@ +Subproject commit 7fd05d17eace3fb8c96882fb4351f84e093f701c
diff --git a/verilog/rtl/qspim/src/filelist.f b/verilog/rtl/qspim/src/filelist.f deleted file mode 100644 index 971ad9f..0000000 --- a/verilog/rtl/qspim/src/filelist.f +++ /dev/null
@@ -1,24 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021, Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org> -// ////////////////////////////////////////////////////////////////////////// - -qspim_top.sv -qspim_regs.sv -qspim_clkgen.sv -qspim_ctrl.sv -qspim_rx.sv -qspim_tx.sv
diff --git a/verilog/rtl/qspim/src/qspim_clkgen.sv b/verilog/rtl/qspim/src/qspim_clkgen.sv deleted file mode 100644 index f163c95..0000000 --- a/verilog/rtl/qspim/src/qspim_clkgen.sv +++ /dev/null
@@ -1,146 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021 , Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> -// -////////////////////////////////////////////////////////////////////// -//// //// -//// SPI Clkgen Module //// -//// //// -//// This file is part of the YIFive cores project //// -//// https://github.com/dineshannayya/yifive_r0.git //// -//// http://www.opencores.org/cores/yifive/ //// -//// //// -//// Description //// -//// This is SPI Master Clock Generation control logic. //// -//// This logic also generate spi clock rise and fall pulse //// -//// Basis assumption is master clock is 2x time spi clock //// -//// 1. spi fall pulse is used to transmit spi data //// -//// 2. spi rise pulse is used to received spi data //// -//// SPI Master Top module //// -//// //// -//// To Do: //// -//// nothing //// -//// //// -//// Author(s): //// -//// - Dinesh Annayya, dinesha@opencores.org //// -//// //// -//// Revision: //// -//// 0.1 - 16th Feb 2021, Dinesh A //// -//// Initial version //// -//// 0.2 - 24th Mar 2021, Dinesh A //// -//// 1. Comments are added //// -//// 2. RTL clean-up done and the output are registred //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000 Authors and OPENCORES.ORG //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source 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 Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// - -module qspim_clkgen -( - input logic clk, - input logic rstn, - input logic en, - input logic [5:0] cfg_sck_period, - output logic spi_clk, - output logic spi_fall, - output logic spi_rise -); - - logic [5:0] sck_half_period; - logic [5:0] clk_cnt; - - assign sck_half_period = {1'b0, cfg_sck_period[5:1]}; - - // The first transition on the sck_toggle happens one SCK period - // after en is asserted - always @(posedge clk or negedge rstn) begin - if(!rstn) begin - spi_clk <= 1'b1; - end // if (!reset_n) - else - begin - if(en) - begin - if(clk_cnt == sck_half_period) - begin - spi_clk <= 1'b0; - end // if (clk_cnt == sck_half_period) - else if(clk_cnt == cfg_sck_period) begin - spi_clk <= 1'b1; - end - end else begin - spi_clk <= 1'b1; - end // else: !if(en) - end // else: !if(!reset_n) - end // always @ (posedge clk or negedge reset_n) - - // Generate Free runnng spi_fall and rise pulse - // after en is asserted - always @(posedge clk or negedge rstn) begin - if(!rstn) begin - clk_cnt <= 'h1; - spi_fall <= 1'b0; - spi_rise <= 1'b0; - end // if (!reset_n) - else - begin - if(clk_cnt == sck_half_period) - begin - spi_fall <= 1'b0; - spi_rise <= 1'b1; - clk_cnt <= clk_cnt + 1'b1; - end // if (clk_cnt == sck_half_period) - else begin - if(clk_cnt == cfg_sck_period) - begin - spi_fall <= 1'b1; - spi_rise <= 1'b0; - clk_cnt <= 'h1; - end // if (clk_cnt == cfg_sck_period) - else - begin - clk_cnt <= clk_cnt + 1'b1; - spi_fall <= 1'b0; - spi_rise <= 1'b0; - end // else: !if(clk_cnt == cfg_sck_period) - end // else: !if(clk_cnt == sck_half_period) - end // else: !if(!reset_n) - end // always @ (posedge clk or negedge reset_n) - -endmodule
diff --git a/verilog/rtl/qspim/src/qspim_ctrl.sv b/verilog/rtl/qspim/src/qspim_ctrl.sv deleted file mode 100644 index 7cd6909..0000000 --- a/verilog/rtl/qspim/src/qspim_ctrl.sv +++ /dev/null
@@ -1,720 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021 , Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> -// -////////////////////////////////////////////////////////////////////// -//// //// -//// SPI CTRL I/F Module //// -//// //// -//// This file is part of the YIFive cores project //// -//// https://github.com/dineshannayya/yifive_r0.git //// -//// http://www.opencores.org/cores/yifive/ //// -//// //// -//// Description //// -//// //// -//// To Do: //// -//// nothing //// -//// //// -//// Author(s): //// -//// - Dinesh Annayya, dinesha@opencores.org //// -//// //// -//// Revision : //// -//// V.0 - June 8, 2021 //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000 Authors and OPENCORES.ORG //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source 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 Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// -module qspim_ctrl #( - parameter ENDIEAN = 0 // 0 - Little, 1 - Big endian, since RISV is Little indian default set 0 - ) - -( - input logic clk, - input logic rstn, - - input logic [7:0] spi_clk_div, - output logic [8:0] spi_status, - - // Master 0 Configuration - input logic [3:0] cfg_m0_cs_reg , // Chip select - input logic [1:0] cfg_m0_spi_mode , // Final SPI Mode - input logic [1:0] cfg_m0_spi_switch, // SPI Mode Switching Place - - input logic [3:0] cfg_m1_cs_reg , // Chip select - input logic [1:0] cfg_m1_spi_mode , // Final SPI Mode - input logic [1:0] cfg_m1_spi_switch, // SPI Mode Switching Place - - input logic [1:0] cfg_cs_early , // Amount of cycle early CS asserted - input logic [1:0] cfg_cs_late , // Amount of cycle late CS de-asserted - - // Master 0 Command FIFO Interface - input logic m0_cmd_fifo_empty, - output logic m0_cmd_fifo_rd, - input logic [33:0] m0_cmd_fifo_rdata, - - // Master 0 response FIFO Interface - output logic m0_res_fifo_flush, - input logic m0_res_fifo_empty, - input logic m0_res_fifo_full, - output logic m0_res_fifo_wr, - output logic [31:0] m0_res_fifo_wdata, - - // Master 1 Command FIFO Interface - output logic m1_res_fifo_flush, - input logic m1_cmd_fifo_empty, - output logic m1_cmd_fifo_rd, - input logic [33:0] m1_cmd_fifo_rdata, - - // Master 1 response FIFO Interface - input logic m1_res_fifo_empty, - input logic m1_res_fifo_full, - output logic m1_res_fifo_wr, - output logic [31:0] m1_res_fifo_wdata, - - output logic [3:0] ctrl_state, - - output logic spi_clk, - output logic spi_csn0, - output logic spi_csn1, - output logic spi_csn2, - output logic spi_csn3, - output logic [1:0] spi_mode, - output logic spi_sdo0, - output logic spi_sdo1, - output logic spi_sdo2, - output logic spi_sdo3, - input logic spi_sdi0, - input logic spi_sdi1, - input logic spi_sdi2, - input logic spi_sdi3, - output logic spi_en_tx_out // Spi Direction control -); - -//-------------------------------------- -// Parameter -// -------------------------------------- -parameter P_SINGLE = 2'b00; -parameter P_DOUBLE = 2'b01; -parameter P_QUAD = 2'b10; -parameter P_QDDR = 2'b11; - - -/************************************************************* -* SPI FSM State Control -* -* OPERATION COMMAND SEQUENCE -* -* ERASE P4E(0x20) -> COMMAND + ADDRESS -* ERASE P8E(0x40) -> COMMAND + ADDRESS -* ERASE SE(0xD8) -> COMMAND + ADDRESS -* ERASE BE(0x60) -> COMMAND + ADDRESS -* ERASE BE(0xC7) -> COMMAND -* PROGRAM PP(0x02) -> COMMAND + ADDRESS + Write DATA -* PROGRAM QPP(0x32) -> COMMAND + ADDRESS + Write DATA -* READ READ(0x3) -> COMMAND + ADDRESS + READ DATA -* READ FAST_READ(0xB) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ DOR (0x3B) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ QOR (0x6B) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ DIOR (0xBB) -> COMMAND + ADDRESS + MODE + READ DATA -* READ QIOR (0xEB) -> COMMAND + ADDRESS + MODE + DUMMY + READ DATA -* READ RDID (0x9F) -> COMMAND + READ DATA -* READ READ_ID (0x90) -> COMMAND + ADDRESS + READ DATA -* WRITE WREN(0x6) -> COMMAND -* WRITE WRDI -> COMMAND -* STATUS RDSR(0x05) -> COMMAND + READ DATA -* STATUS RCR(0x35) -> COMMAND + READ DATA -* CONFIG WRR(0x01) -> COMMAND + WRITE DATA -* CONFIG CLSR(0x30) -> COMMAND -* Power Saving DP(0xB9) -> COMMAND -* Power Saving RES(0xAB) -> COMMAND + READ DATA -* OTP OTPP(0x42) -> COMMAND + ADDR+ WRITE DATA -* OTP OTPR(0x4B) -> COMMAND + ADDR + DUMMY + READ DATA -* ********************************************************************/ -parameter P_FSM_C = 4'b0000; // Command Phase Only -parameter P_FSM_CW = 4'b0001; // Command + Write DATA Phase Only -parameter P_FSM_CA = 4'b0010; // Command -> Address Phase Only - -parameter P_FSM_CAR = 4'b0011; // Command -> Address -> Read Data -parameter P_FSM_CADR = 4'b0100; // Command -> Address -> Dummy -> Read Data -parameter P_FSM_CAMR = 4'b0101; // Command -> Address -> Mode -> Read Data -parameter P_FSM_CAMDR = 4'b0110; // Command -> Address -> Mode -> Dummy -> Read Data - -parameter P_FSM_CAW = 4'b0111; // Command -> Address ->Write Data -parameter P_FSM_CADW = 4'b1000; // Command -> Address -> DUMMY + Write Data - -parameter P_FSM_CDR = 4'b1001; // COMMAND -> DUMMY -> READ -parameter P_FSM_CDW = 4'b1010; // COMMAND -> DUMMY -> WRITE -parameter P_FSM_CR = 4'b1011; // COMMAND -> READ - -//--------------------- - parameter P_8BIT = 2'b00; - parameter P_16BIT = 2'b01; - parameter P_24BIT = 2'b10; - parameter P_32BIT = 2'b11; - -//---- Phase where to switch the SPI Mode -//---- This need to decided based on command - parameter P_MODE_SWITCH_IDLE = 2'b00; - parameter P_MODE_SWITCH_AT_ADDR = 2'b01; - parameter P_MODE_SWITCH_AT_DATA = 2'b10; -//---------------------------------------- -// Local Variable -// --------------------------------------- - logic spi_rise; - logic spi_fall; - - logic spi_clock_en; - - logic spi_en_rx; - logic spi_en_tx; - - - logic [15:0] counter_tx; - logic counter_tx_valid; - logic [15:0] counter_rx; - logic counter_rx_valid; - - logic dummy_phase; - logic [31:0] data_to_tx; - logic data_to_tx_valid; - logic data_to_tx_ready; - logic tx_data_ready; - - - logic tx_done; - logic rx_done; - - logic [1:0] s_spi_mode; - - logic ctrl_data_valid; - - logic spi_cs; - - logic tx_clk_en; - logic rx_clk_en; - logic [1:0] cnt; // counter for cs assertion and de-assertion - logic [1:0] nxt_cnt; - logic [1:0] gnt; - - logic [7:0] cfg_data_cnt ; - logic [1:0] cfg_dummy_cnt ; - logic [1:0] cfg_addr_cnt ; - logic [3:0] cfg_spi_seq ; - logic [7:0] spi_mode_cmd ; - - - enum logic [2:0] {DATA_NULL,DATA_EMPTY,DATA_CMD,DATA_ADDR,DATA_MODE,DATA_FIFO} ctrl_data_mux; - - enum logic [4:0] {FSM_IDLE,FSM_CS_ASSERT,FSM_CMD_PHASE,FSM_ADR_PHASE,FSM_DUMMY_PHASE,FSM_MODE_PHASE,FSM_WRITE_CMD,FSM_WRITE_PHASE, - FSM_READ_WAIT,FSM_READ_PHASE,FSM_TX_DONE,FSM_FLUSH,FSM_CS_DEASEERT} state,next_state; - - - assign ctrl_state = state[3:0]; - - assign spi_mode = s_spi_mode; - - //---------------------------- - // Configuration - //---------------------------- - logic [3:0] cfg_cs_reg ; // Chip select - logic [1:0] cfg_spi_mode ; // Final SPI Mode - logic [1:0] cfg_spi_switch; // SPI Mode Switching Place - - - assign cfg_cs_reg = (gnt == 2'b01) ? cfg_m0_cs_reg : cfg_m1_cs_reg; - assign cfg_spi_mode = (gnt == 2'b01) ? cfg_m0_spi_mode : cfg_m1_spi_mode; // Final SPI Mode - assign cfg_spi_switch = (gnt == 2'b01) ? cfg_m0_spi_switch: cfg_m1_spi_switch; // SPI Mode Switching Place - - //---------------------------- - // Command FIFO - //---------------------------- - logic cmd_fifo_empty; - logic cmd_fifo_rd; - logic [33:0] cmd_fifo_rdata; - - assign cmd_fifo_empty = (gnt == 2'b01) ? m0_cmd_fifo_empty : m1_cmd_fifo_empty; - assign cmd_fifo_rdata = (gnt == 2'b01) ? m0_cmd_fifo_rdata : m1_cmd_fifo_rdata; - - assign m0_cmd_fifo_rd = (gnt == 2'b01) ? cmd_fifo_rd : 1'b0; - assign m1_cmd_fifo_rd = (gnt == 2'b10) ? cmd_fifo_rd : 1'b0; - - //---------------------------- - // Response FIFO - //---------------------------- - logic res_fifo_empty; - logic res_fifo_full; - logic res_fifo_wr; - logic [31:0] res_fifo_wdata; - - assign res_fifo_empty = (gnt == 2'b01) ? m0_res_fifo_empty : m1_res_fifo_empty; - assign res_fifo_full = (gnt == 2'b01) ? m0_res_fifo_full : m1_res_fifo_full; - - assign m0_res_fifo_wr = (gnt == 2'b01) ? res_fifo_wr : 1'b0; - assign m1_res_fifo_wr = (gnt == 2'b10) ? res_fifo_wr : 1'b0; - - assign m0_res_fifo_wdata = (gnt == 2'b01) ? res_fifo_wdata : 1'b0; - assign m1_res_fifo_wdata = (gnt == 2'b10) ? res_fifo_wdata : 1'b0; - - //--------------------------------------------------------------------------- - // To take care of partial/stall data in response fifo - // we are flushing the content - // - // WARNING: This will work well for burst size 4, - // If User given 6 Word Burst and Read only one location - // Read Path will hang waiting for Response FIFO to empty, User need to take - // care of partial reading case. - //--------------------------------------------------------------------------- - - logic fsm_flush; - logic spi_dummy; - assign m0_res_fifo_flush = (gnt == 2'b01) ? fsm_flush : 1'b0; - assign m1_res_fifo_flush = (gnt == 2'b10) ? fsm_flush : 1'b0; - - assign spi_clock_en = tx_clk_en | rx_clk_en; - - assign spi_en_tx_out = (spi_en_tx) && (spi_dummy ==0); // Don't Drive Tx On Dummy Phase - - qspim_clkgen u_clkgen - ( - .clk ( clk ), - .rstn ( rstn ), - .en ( spi_clock_en ), - .cfg_sck_period ( spi_clk_div [5:0] ), - .spi_clk ( spi_clk ), - .spi_fall ( spi_fall ), - .spi_rise ( spi_rise ) - ); - qspim_tx u_txreg - ( - .clk ( clk ), - .rstn ( rstn ), - .flush ( fsm_flush ), - .en ( spi_en_tx ), - .tx_edge ( spi_fall ), - .tx_done ( tx_done ), - .sdo0 ( spi_sdo0 ), - .sdo1 ( spi_sdo1 ), - .sdo2 ( spi_sdo2 ), - .sdo3 ( spi_sdo3 ), - .s_spi_mode ( s_spi_mode ), - .counter_in ( counter_tx ), - .counter_in_upd ( counter_tx_valid ), - .dummy_phase ( dummy_phase ), - .txdata ( data_to_tx ), - .data_valid ( data_to_tx_valid ), - .data_ready ( tx_data_ready ), - .spi_dummy ( spi_dummy ), - .clk_en_o ( tx_clk_en ) - ); - qspim_rx #(.ENDIEAN(ENDIEAN)) u_rxreg - ( - .clk ( clk ), - .rstn ( rstn ), - .flush ( fsm_flush ), - .en ( spi_en_rx ), - .rx_edge ( spi_rise ), - .rx_done ( rx_done ), - .sdi0 ( spi_sdi0 ), - .sdi1 ( spi_sdi1 ), - .sdi2 ( spi_sdi2 ), - .sdi3 ( spi_sdi3 ), - .s_spi_mode ( s_spi_mode ), - .counter_in ( counter_rx ), - .counter_in_upd ( counter_rx_valid ), - .data ( res_fifo_wdata ), - .data_valid ( res_fifo_wr ), - .data_ready ( !res_fifo_full ), - .clk_en_o ( rx_clk_en ) - ); - - always_comb - begin - data_to_tx = 'h0; - data_to_tx_valid = 1'b0; - dummy_phase = 1'b0; - - case(ctrl_data_mux) - DATA_NULL: - begin - data_to_tx = '0; - data_to_tx_valid = 1'b0; - end - - DATA_EMPTY: - begin - dummy_phase = 1'b1; - data_to_tx = '0; - data_to_tx_valid = 1'b1; - end - - DATA_CMD: - begin - data_to_tx = {cmd_fifo_rdata[7:0],24'h0}; - data_to_tx_valid = ctrl_data_valid; - end - DATA_MODE: - begin - data_to_tx = {spi_mode_cmd,24'h0}; - data_to_tx_valid = ctrl_data_valid; - end - - DATA_ADDR: - begin - data_to_tx = (cfg_addr_cnt == P_8BIT) ? {cmd_fifo_rdata[7:0],24'h0} : - (cfg_addr_cnt == P_16BIT) ? {cmd_fifo_rdata[15:0],16'h0} : - (cfg_addr_cnt == P_24BIT) ? {cmd_fifo_rdata[23:0],8'h0} : {cmd_fifo_rdata[31:0]}; - data_to_tx_valid = ctrl_data_valid; - end - - // RISV is little endian, so data is converted to little endian format - DATA_FIFO: begin - data_to_tx = (ENDIEAN) ? cmd_fifo_rdata[31:0] : - {cmd_fifo_rdata[7:0],cmd_fifo_rdata[15:8],cmd_fifo_rdata[23:16],cmd_fifo_rdata[31:24]}; - data_to_tx_valid = !cmd_fifo_empty; - end - endcase - end - - always_comb - begin - fsm_flush = 0; - counter_tx = '0; - counter_tx_valid = 1'b0; - counter_rx = '0; - counter_rx_valid = 1'b0; - next_state = state; - ctrl_data_mux = DATA_NULL; - ctrl_data_valid = 1'b0; - spi_en_rx = 1'b0; - spi_en_tx = 1'b0; - spi_status = '0; - cmd_fifo_rd = 1'b0; - nxt_cnt = cnt; - case(state) - FSM_IDLE: - begin - spi_status[0] = 1'b1; - nxt_cnt = 0; - if(!m0_cmd_fifo_empty || !m1_cmd_fifo_empty ) begin - next_state = FSM_CS_ASSERT; - end - end - - // Asserted CS# low - FSM_CS_ASSERT: begin - fsm_flush=1; // Flush stale data in response fifo - if(cfg_cs_early == cnt) begin - next_state = FSM_CMD_PHASE; - end else begin - nxt_cnt = nxt_cnt+1; - end - end - - // WAIT for COMMAND Phase Completed - FSM_CMD_PHASE: begin - counter_tx = 8'h8; - ctrl_data_mux = DATA_CMD; - ctrl_data_valid = 1'b1; - counter_tx = 'd8; - counter_tx_valid = 1'b1; - spi_en_tx = 1'b1; - if (tx_data_ready) begin - cmd_fifo_rd = 1'b1; - case(cfg_spi_seq) - P_FSM_C: next_state = FSM_TX_DONE; - P_FSM_CW: next_state = FSM_WRITE_CMD; - P_FSM_CA: next_state = FSM_ADR_PHASE; - P_FSM_CAR: next_state = FSM_ADR_PHASE; - P_FSM_CADR: next_state = FSM_ADR_PHASE; - P_FSM_CAMR: next_state = FSM_ADR_PHASE; - P_FSM_CAMDR: next_state = FSM_ADR_PHASE; - P_FSM_CAW: next_state = FSM_ADR_PHASE; - P_FSM_CADW: next_state = FSM_ADR_PHASE; - P_FSM_CDR: next_state = FSM_DUMMY_PHASE; - P_FSM_CDW: next_state = FSM_DUMMY_PHASE; - P_FSM_CR: next_state = FSM_READ_WAIT; - default : next_state = FSM_TX_DONE; - endcase - end - end - - // WAIT for ADDR Command Accepted - FSM_ADR_PHASE: begin - nxt_cnt = 0; - ctrl_data_mux = DATA_ADDR; - ctrl_data_valid = 1'b1; - counter_tx = (cfg_addr_cnt == P_8BIT) ? 'd8 : - (cfg_addr_cnt == P_16BIT) ? 'd16 : - (cfg_addr_cnt == P_24BIT) ? 'd24 : 'd32; - counter_tx_valid = 1'b1; - spi_en_tx = 1'b1; - if (tx_data_ready) begin - ctrl_data_valid = 1'b0; - cmd_fifo_rd = 1'b1; - case(cfg_spi_seq) - P_FSM_CA: next_state = FSM_TX_DONE; - P_FSM_CAR: next_state = FSM_READ_WAIT; - P_FSM_CADR: next_state = FSM_DUMMY_PHASE; - P_FSM_CAMR: next_state = FSM_MODE_PHASE; - P_FSM_CAMDR: next_state = FSM_MODE_PHASE; - P_FSM_CAW: next_state = FSM_WRITE_CMD; - P_FSM_CADW: next_state = FSM_DUMMY_PHASE; - default : next_state = FSM_TX_DONE; - endcase - end - end - - // WAIT for DUMMY command Accepted - FSM_DUMMY_PHASE: begin - nxt_cnt = 0; - ctrl_data_mux = DATA_EMPTY; - ctrl_data_valid = 1'b1; - counter_tx_valid = 1'b1; - if(s_spi_mode == P_QDDR ) begin - // QDDR Mode, change the Dummy cycle values to 32,40,48,56 - counter_tx = (cfg_dummy_cnt == 2'b00) ? 'd32 : - (cfg_dummy_cnt == 2'b01) ? 'd40 : - (cfg_dummy_cnt == 2'b10) ? 'd48 : 'd56; - end else begin - counter_tx = (cfg_dummy_cnt == P_8BIT) ? 'd8 : - (cfg_dummy_cnt == P_16BIT) ? 'd16 : - (cfg_dummy_cnt == P_24BIT) ? 'd24 : 'd32; - end - spi_en_tx = 1'b1; - if (tx_data_ready) begin - ctrl_data_valid = 1'b0; - case(cfg_spi_seq) - P_FSM_CADR: next_state = FSM_READ_WAIT; - P_FSM_CAMDR: next_state = FSM_READ_WAIT; - P_FSM_CADW: next_state = FSM_WRITE_CMD; - P_FSM_CDR: next_state = FSM_READ_WAIT; - P_FSM_CDW: next_state = FSM_WRITE_CMD; - default : next_state = FSM_CS_DEASEERT; - endcase - end - end - // WAIT for MODE command accepted - FSM_MODE_PHASE: begin - nxt_cnt = 0; - ctrl_data_mux = DATA_MODE; - ctrl_data_valid = 1'b1; - counter_tx_valid = 1'b1; - counter_tx = 'd8; - spi_en_tx = 1'b1; - if (tx_data_ready) begin - case(cfg_spi_seq) - P_FSM_CAMR: next_state = FSM_READ_WAIT; - P_FSM_CAMDR: next_state = FSM_DUMMY_PHASE; - default : next_state = FSM_CS_DEASEERT; - endcase - end - end - - // Wait for WRITE COMMAND ACCEPTED - FSM_WRITE_CMD: begin - nxt_cnt = 0; - ctrl_data_mux = DATA_FIFO; - ctrl_data_valid = 1'b1; - counter_tx_valid = 1'b1; - counter_tx = {5'b0,cfg_data_cnt[7:0],3'b000}; // Convert Byte to Bit Count - spi_en_tx = 1'b1; - if (tx_data_ready) begin - cmd_fifo_rd = 1'b1; - next_state = FSM_WRITE_PHASE; - end - end - - // Wait for ALL WRITE DATA ACCEPTED - FSM_WRITE_PHASE: begin - nxt_cnt = 0; - ctrl_data_mux = DATA_FIFO; - ctrl_data_valid = 1'b1; - spi_en_tx = 1'b1; - if (tx_done) begin - next_state = FSM_CS_DEASEERT; - end else if(tx_data_ready && cmd_fifo_empty == 0) begin - // Once Current Data is accepted by TX FSM, check FIFO not empty - // and read next location - cmd_fifo_rd = 1'b1; - end - end - - // Wait for Previous TX Completeion - FSM_READ_WAIT: begin - spi_en_tx = 1'b1; - if (tx_done) begin - next_state = FSM_READ_PHASE; - end - end - - FSM_READ_PHASE: begin - nxt_cnt = 0; - counter_rx_valid = 1'b1; - counter_rx = {5'b0,cfg_data_cnt[7:0],3'b000}; // Convert Byte to Bit Count - spi_en_rx = 1'b1; - if(!cmd_fifo_empty) begin - // If you see new command request, then abort the current request - next_state = FSM_FLUSH; - end else begin - if (rx_done) begin - next_state = FSM_CS_DEASEERT; - end - end - end - - FSM_FLUSH: begin - fsm_flush = 1; - // Wait for safe SPI-clock de-assertion phase - if(spi_clock_en ==0) begin - next_state = FSM_CS_DEASEERT; - end - end - // Wait for TX Done - FSM_TX_DONE: begin - spi_en_tx = 1'b1; - if(tx_done) next_state = FSM_CS_DEASEERT; - end - - // De-assert CS# - FSM_CS_DEASEERT: begin - if(cfg_cs_late == cnt) begin - next_state = FSM_IDLE; - end else begin - nxt_cnt = nxt_cnt+1; - end - end - endcase -end - - - - - always @(posedge clk or negedge rstn) begin - if (rstn == 1'b0) begin - state <= FSM_IDLE; - cnt <= 'h0; - end else begin - state <= next_state; - cnt <= nxt_cnt; - end - end - - //--------------------------------------------------------------------- - // Grant Generation Based on FIFO empty, priority given to Master 0 - // Grant switch happens only at FSM IDLE State - // --------------------------------------------------------------------- - - always @(posedge clk or negedge rstn) begin - if (rstn == 1'b0) begin - gnt <= 0; - spi_mode_cmd <= 'h0; - cfg_spi_seq <= 'h0; - cfg_addr_cnt <= 'h0; - cfg_dummy_cnt <= 'h0; - cfg_data_cnt <= 'h0; - end else begin - if(state == FSM_IDLE) begin - if(!m0_cmd_fifo_empty) begin - cfg_data_cnt <= m0_cmd_fifo_rdata[31:24]; - cfg_dummy_cnt <= m0_cmd_fifo_rdata[23:22]; - cfg_addr_cnt <= m0_cmd_fifo_rdata[21:20]; - cfg_spi_seq <= m0_cmd_fifo_rdata[19:16]; - spi_mode_cmd <= m0_cmd_fifo_rdata[15:8]; - gnt <= 2'b01; - end - else if(!m1_cmd_fifo_empty ) begin - cfg_data_cnt <= m1_cmd_fifo_rdata[31:24]; - cfg_dummy_cnt <= m1_cmd_fifo_rdata[23:22]; - cfg_addr_cnt <= m1_cmd_fifo_rdata[21:20]; - cfg_spi_seq <= m1_cmd_fifo_rdata[19:16]; - spi_mode_cmd <= m1_cmd_fifo_rdata[15:8]; - gnt <= 2'b10; - end - end - end - end - - - //----------------------------------------------------------------------- - // SPI Mode Switch Control Logic - // Note: SPI Protocl Start with SPI_STD Mode (Sigle Bit Mode) Base on the - // Command, Type it Switch the mode at ADDRESS/DUMMY/DATA Phase - // QIOR(0xEB) -> Mode switch at Address Phase - // DIOR(0xBB) -> Mode Switch at Address Phase - // QOR (0x6B) -> Mode Switch at Data Phase - // DOR (0x3B) -> Mode Switch at Data Phase - // QPP (0x32) -> Mode Switch at Data Phase - // ---------------------------------------------------------------------- - always @(posedge clk or negedge rstn) begin - if (rstn == 1'b0) begin - s_spi_mode <= P_SINGLE; - end else begin - if(state == FSM_IDLE) begin // Reset the Mode at IDLE State - s_spi_mode <= P_SINGLE; - end else if(state == FSM_ADR_PHASE && cfg_spi_switch == P_MODE_SWITCH_AT_ADDR) begin - s_spi_mode <= cfg_spi_mode; - end else if(((state == FSM_READ_PHASE) || state == FSM_WRITE_CMD ) && cfg_spi_switch == P_MODE_SWITCH_AT_DATA) begin - s_spi_mode <= cfg_spi_mode; - end - end - end - - // SPI Chip Select Logic - always @(posedge clk or negedge rstn) begin - if (rstn == 1'b0) begin - spi_csn0 <= 1'b1; - spi_csn1 <= 1'b1; - spi_csn2 <= 1'b1; - spi_csn3 <= 1'b1; - end else begin - if(state != FSM_IDLE) begin - spi_csn0 <= ~cfg_cs_reg[0]; - spi_csn1 <= ~cfg_cs_reg[1]; - spi_csn2 <= ~cfg_cs_reg[2]; - spi_csn3 <= ~cfg_cs_reg[3]; - end else begin - spi_csn0 <= 1'b1; - spi_csn1 <= 1'b1; - spi_csn2 <= 1'b1; - spi_csn3 <= 1'b1; - end - end - end - -endmodule
diff --git a/verilog/rtl/qspim/src/qspim_fifo.sv b/verilog/rtl/qspim/src/qspim_fifo.sv deleted file mode 100644 index 2b8bf73..0000000 --- a/verilog/rtl/qspim/src/qspim_fifo.sv +++ /dev/null
@@ -1,227 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021 , Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> -// -/********************************************************************* - - SYNC FIFO - - This file is part of the yifive project - https://github.com/dineshannayya/yifive_r0.git - - Description: SYNC FIFO - - To Do: - nothing - - Author(s): Dinesh Annayya, dinesha@opencores.org - - Copyright (C) 2000 Authors and OPENCORES.ORG - - This source file may be used and distributed without - restriction provided that this copyright statement is not - removed from the file and that any derivative work contains - the original copyright notice and the associated disclaimer. - - This source file is free software; you can redistribute it - and/or modify it under the terms of the GNU Lesser General - Public License as published by the Free Software Foundation; - either version 2.1 of the License, or (at your option) any -later version. - - This source 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 Lesser General Public License for more - details. - - You should have received a copy of the GNU Lesser General - Public License along with this source; if not, download it - from http://www.opencores.org/lgpl.shtml - -*******************************************************************/ - -//------------------------------------------- -// sync FIFO -//----------------------------------------------- -//`timescale 1ns/1ps - -module qspim_fifo (clk, - reset_n, - flush, - wr_en, - wr_data, - full, - afull, - rd_en, - empty, - aempty, - rd_data); - - parameter W = 4'd8; - parameter DP = 3'd4; - parameter WR_FAST = 1'b1; - parameter RD_FAST = 1'b1; - parameter FULL_DP = DP; - parameter EMPTY_DP = 1'b0; - - parameter AW = (DP == 2) ? 1 : - (DP == 4) ? 2 : - (DP == 8) ? 3 : - (DP == 16) ? 4 : - (DP == 32) ? 5 : - (DP == 64) ? 6 : - (DP == 128) ? 7 : - (DP == 256) ? 8 : 0; - - output [W-1 : 0] rd_data; - input [W-1 : 0] wr_data; - input clk, reset_n, wr_en,flush, - rd_en; - output full, empty; - output afull, aempty; // about full and about to empty - - - // synopsys translate_off - - initial begin - if (AW == 0) begin - $display ("%m : ERROR!!! Fifo depth %d not in range 2 to 256", DP); - end // if (AW == 0) - end // initial begin - - // synopsys translate_on - - reg [W-1 : 0] mem[DP-1 : 0]; - - /*********************** write side ************************/ - reg [AW:0] wr_ptr; - reg full_q; - wire full_c; - wire afull_c; - wire [AW:0] wr_ptr_inc = wr_ptr + 1'b1; - wire [AW:0] wr_cnt = get_cnt(wr_ptr, rd_ptr); - - assign full_c = (wr_cnt == FULL_DP) ? 1'b1 : 1'b0; - assign afull_c = (wr_cnt == FULL_DP-1) ? 1'b1 : 1'b0; - - - always @(posedge clk or negedge reset_n) begin - if (!reset_n) begin - wr_ptr <= 0; - full_q <= 0; - end - else begin - if(flush) begin - wr_ptr <= 0; - full_q <= 0; - end else if (wr_en) begin - wr_ptr <= wr_ptr_inc; - if (wr_cnt == (FULL_DP-1)) begin - full_q <= 1'b1; - end - end else begin - if (full_q && (wr_cnt<FULL_DP)) begin - full_q <= 1'b0; - end - end - end - end - - assign full = (WR_FAST == 1) ? full_c : full_q; - assign afull = afull_c; - - always @(posedge clk) begin - if (wr_en) begin - mem[wr_ptr[AW-1:0]] <= wr_data; - end - end - - - /************************ read side *****************************/ - reg [AW:0] rd_ptr; - reg empty_q; - wire empty_c; - wire aempty_c; - wire [AW:0] rd_ptr_inc = rd_ptr + 1'b1; - wire [AW:0] rd_cnt = get_cnt(wr_ptr, rd_ptr); - - assign empty_c = (rd_cnt == 0) ? 1'b1 : 1'b0; - assign aempty_c = (rd_cnt == 1) ? 1'b1 : 1'b0; - - always @(posedge clk or negedge reset_n) begin - if (!reset_n) begin - rd_ptr <= 0; - empty_q <= 1'b1; - end - else begin - if(flush) begin - rd_ptr <= 0; - empty_q <= 1'b1; - end else if (rd_en) begin - rd_ptr <= rd_ptr_inc; - if (rd_cnt==(EMPTY_DP+1)) begin - empty_q <= 1'b1; - end - end else begin - if (empty_q && (rd_cnt!=EMPTY_DP)) begin - empty_q <= 1'b0; - end - end - end - end - - assign empty = (RD_FAST == 1) ? empty_c : empty_q; - assign aempty = aempty_c; - - reg [W-1 : 0] rd_data_q; - - wire [W-1 : 0] rd_data_c = mem[rd_ptr[AW-1:0]]; - always @(posedge clk) begin - rd_data_q <= rd_data_c; - end - assign rd_data = (RD_FAST == 1) ? rd_data_c : rd_data_q; - - -function [AW:0] get_cnt; -input [AW:0] wr_ptr, rd_ptr; -begin - if (wr_ptr >= rd_ptr) begin - get_cnt = (wr_ptr - rd_ptr); - end - else begin - get_cnt = DP*2 - (rd_ptr - wr_ptr); - end -end -endfunction - -// synopsys translate_off -always @(posedge clk) begin - if (wr_en && full) begin - $display($time, "%m Error! afifo overflow!"); - $stop; - end -end - -always @(posedge clk) begin - if (rd_en && empty) begin - $display($time, "%m error! afifo underflow!"); - $stop; - end -end -// synopsys translate_on - -endmodule
diff --git a/verilog/rtl/qspim/src/qspim_if.sv b/verilog/rtl/qspim/src/qspim_if.sv deleted file mode 100644 index 7d7d7ab..0000000 --- a/verilog/rtl/qspim/src/qspim_if.sv +++ /dev/null
@@ -1,335 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021 , Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> -// -////////////////////////////////////////////////////////////////////// -//// //// -//// SPI WishBone I/F Module //// -//// //// -//// This file is part of the YIFive cores project //// -//// https://github.com/dineshannayya/yifive_r0.git //// -//// http://www.opencores.org/cores/yifive/ //// -//// //// -//// Description //// -//// SPI WishBone I/F module //// -//// This block support following functionality //// -//// 1. This block Response to Direct Memory Read and //// -//// Register Write and Read Command //// -//// 2. In case of Direct Memory Read, It check send the //// -//// SPI Read command to SPI Ctrl logic and wait for //// -//// Read data through Response //// -//// //// -//// To Do: //// -//// 1. Add 4 Word Memory Fetch for better Through Put //// -//// //// -//// Author(s): //// -//// - Dinesh Annayya, dinesha@opencores.org //// -//// //// -//// Revision : //// -//// V.0 - June 30, 2021 //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000 Authors and OPENCORES.ORG //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source 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 Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// - - -module qspim_if #( parameter WB_WIDTH = 32) ( - input logic mclk, - input logic rst_n, - - input logic wbd_stb_i, // strobe/request - input logic [WB_WIDTH-1:0] wbd_adr_i, // address - input logic wbd_we_i, // write - input logic [WB_WIDTH-1:0] wbd_dat_i, // data output - input logic [3:0] wbd_sel_i, // byte enable - output logic [WB_WIDTH-1:0] wbd_dat_o, // data input - output logic wbd_ack_o, // acknowlegement - output logic wbd_err_o, // error - - - // Configuration - input logic cfg_fsm_reset, - input logic [3:0] cfg_mem_seq, // SPI MEM SEQUENCE - input logic [1:0] cfg_addr_cnt, // SPI Addr Count - input logic [1:0] cfg_dummy_cnt, // SPI Dummy Count - input logic [7:0] cfg_data_cnt, // SPI Read Count - input logic [7:0] cfg_cmd_reg, // SPI MEM COMMAND - input logic [7:0] cfg_mode_reg, // SPI MODE REG - input logic spi_init_done, // SPI internal Init completed - - // Towards Reg I/F - output logic spim_reg_req, // Reg Request - output logic [3:0] spim_reg_addr, // Reg Address - output logic spim_reg_we, // Reg Write/Read Command - output logic [3:0] spim_reg_be, // Reg Byte Enable - output logic [31:0] spim_reg_wdata, // Reg Write Data - input logic spim_reg_ack, // Read Ack - input logic [31:0] spim_reg_rdata, // Read Read Data - - // Towards Command FIFO - input logic cmd_fifo_empty, // Command FIFO empty - output logic cmd_fifo_wr, // Command FIFO Write - output logic [33:0] cmd_fifo_wdata, // Command FIFO WData - - // Towards Response FIFO - input logic res_fifo_empty, // Response FIFO Empty - output logic res_fifo_rd, // Response FIFO Read - input logic [31:0] res_fifo_rdata, // Response FIFO Data - - output logic [3:0] state - ); - -//------------------------------------------------ -// Parameter Decleration -// ----------------------------------------------- -parameter SOC = 1'b1; // START of COMMAND -parameter EOC = 1'b1; // END of COMMAND -parameter NOC = 1'b0; // NORMAL COMMAND - -// State Machine state -parameter IDLE = 4'b000; -parameter ADR_PHASE = 4'b001; -parameter CMD_WAIT = 4'b010; -parameter READ_DATA = 4'b011; - -/************************************************************* -* SPI FSM State Control -* -* OPERATION COMMAND SEQUENCE -* -* ERASE P4E(0x20) -> COMMAND + ADDRESS -* ERASE P8E(0x40) -> COMMAND + ADDRESS -* ERASE SE(0xD8) -> COMMAND + ADDRESS -* ERASE BE(0x60) -> COMMAND + ADDRESS -* ERASE BE(0xC7) -> COMMAND -* PROGRAM PP(0x02) -> COMMAND + ADDRESS + Write DATA -* PROGRAM QPP(0x32) -> COMMAND + ADDRESS + Write DATA -* READ READ(0x3) -> COMMAND + ADDRESS + READ DATA -* READ FAST_READ(0xB) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ DOR (0x3B) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ QOR (0x6B) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ DIOR (0xBB) -> COMMAND + ADDRESS + MODE + READ DATA -* READ QIOR (0xEB) -> COMMAND + ADDRESS + MODE + DUMMY + READ DATA -* READ RDID (0x9F) -> COMMAND + READ DATA -* READ READ_ID (0x90) -> COMMAND + ADDRESS + READ DATA -* WRITE WREN(0x6) -> COMMAND -* WRITE WRDI -> COMMAND -* STATUS RDSR(0x05) -> COMMAND + READ DATA -* STATUS RCR(0x35) -> COMMAND + READ DATA -* CONFIG WRR(0x01) -> COMMAND + WRITE DATA -* CONFIG CLSR(0x30) -> COMMAND -* Power Saving DP(0xB9) -> COMMAND -* Power Saving RES(0xAB) -> COMMAND + READ DATA -* OTP OTPP(0x42) -> COMMAND + ADDR+ WRITE DATA -* OTP OTPR(0x4B) -> COMMAND + ADDR + DUMMY + READ DATA -* ********************************************************************/ - -parameter P_FSM_C = 4'b0000; // Command Phase Only -parameter P_FSM_CA = 4'b0001; // Command -> Address Phase Only - -parameter P_FSM_CAR = 4'b0010; // Command -> Address -> Read Data -parameter P_FSM_CADR = 4'b0011; // Command -> Address -> Dummy -> Read Data -parameter P_FSM_CAMR = 4'b0100; // Command -> Address -> Mode -> Read Data -parameter P_FSM_CAMDR = 4'b0101; // Command -> Address -> Mode -> Dummy -> Read Data - -parameter P_FSM_CAW = 4'b0110; // Command -> Address ->Write Data -parameter P_FSM_CADW = 4'b0111; // Command -> Address -> DUMMY + Write Data -//--------------------------------------------------------- -// Variable declartion -// ------------------------------------------------------- -logic spim_mem_req ; // Current Request is Direct Memory Read - - -logic spim_wb_req ; -logic [WB_WIDTH-1:0] spim_wb_wdata ; -logic [WB_WIDTH-1:0] spim_wb_addr ; -logic spim_wb_ack ; -logic spim_wb_we ; -logic [3:0] spim_wb_be ; -logic [WB_WIDTH-1:0] spi_mem_rdata ; -logic [WB_WIDTH-1:0] spim_wb_rdata ; - -logic spim_mem_ack ; -logic [3:0] next_state ; - -logic NextPreDVal ; -logic [7:0] NextPreDCnt ; -logic [31:0] NextPreAddr ; - - - //--------------------------------------------------------------- - // Address Decoding - // 0x0000_0000 - 0x0FFF_FFFF - SPI FLASH MEMORY ACCESS - 256MB - // 0x1000_0000 - - SPI Register Access - // - // - // Note: Only Bit[28] is decoding done here, other Bit decoding - // will be done inside the wishbone inter-connect - // -------------------------------------------------------------- - - assign spim_mem_req = ((spim_wb_req) && spim_wb_addr[28] == 1'b0); - assign spim_reg_req = ((spim_wb_req) && spim_wb_addr[28] == 1'b1); - - assign spim_reg_addr = spim_wb_addr[5:2]; - assign spim_reg_wdata = spim_wb_wdata; - assign spim_reg_we = spim_wb_we; - assign spim_reg_be = spim_wb_be; - - assign wbd_dat_o = spim_wb_rdata; - assign wbd_ack_o = spim_wb_ack; - assign wbd_err_o = 1'b0; - - // To reduce the load/Timing Wishbone I/F, all the variable are registered -always_ff @(negedge rst_n or posedge mclk) begin - if ( rst_n == 1'b0 ) begin - spim_wb_req <= '0; - spim_wb_wdata <= '0; - spim_wb_rdata <= '0; - spim_wb_addr <= '0; - spim_wb_be <= '0; - spim_wb_we <= '0; - spim_wb_ack <= '0; - end else begin - if(spi_init_done) begin // Wait for internal SPI Init Done - spim_wb_req <= wbd_stb_i && ((spim_wb_ack == 0) && (spim_mem_ack ==0) && (spim_reg_ack == 0)); - spim_wb_wdata <= wbd_dat_i; - spim_wb_addr <= wbd_adr_i; - spim_wb_be <= wbd_sel_i; - spim_wb_we <= wbd_we_i; - - - if(!spim_wb_we && spim_mem_req && spim_mem_ack) - spim_wb_rdata <= spi_mem_rdata; - else if (spim_reg_req && spim_reg_ack) - spim_wb_rdata <= spim_reg_rdata; - - spim_wb_ack <= (spim_mem_req) ? spim_mem_ack : - (spim_reg_req) ? spim_reg_ack : 1'b0; - end - end -end - - -always_ff @(negedge rst_n or posedge mclk) begin - if ( rst_n == 1'b0 ) begin - state <= IDLE; - end else begin - if(cfg_fsm_reset) state <= IDLE; - else state <= next_state; - end -end - -/*********************************************************************************** -* This block interface with WishBone Request and Write Command & Read Response FIFO -* **********************************************************************************/ - -always_comb -begin - cmd_fifo_wr = '0; - cmd_fifo_wdata = '0; - res_fifo_rd = 0; - spi_mem_rdata = '0; - - spim_mem_ack = 0; - next_state = state; - case(state) - IDLE: begin - // Check If any prefetch data available and if see it matched with WB - // address, If yes, the move to data reading from response fifo, else - // generate command request - if(spim_mem_req && NextPreDVal && (spim_wb_addr == NextPreAddr)) begin - next_state = READ_DATA; - end else if(spim_mem_req && cmd_fifo_empty) begin - cmd_fifo_wdata = {SOC,NOC,cfg_data_cnt[7:0],cfg_dummy_cnt[1:0],cfg_addr_cnt[1:0],cfg_mem_seq[3:0],cfg_mode_reg[7:0],cfg_cmd_reg[7:0]}; - cmd_fifo_wr = 1; - next_state = ADR_PHASE; - end - end - ADR_PHASE: begin - cmd_fifo_wdata = {NOC,EOC,spim_wb_addr[31:0]}; - cmd_fifo_wr = 1; - next_state = CMD_WAIT; - end - CMD_WAIT: begin - // Wait for Command Accepted, before reading data - // to take care of staled data being read due to pre-fetch logic - if(cmd_fifo_empty) next_state = READ_DATA; - end - - - READ_DATA: begin - if(res_fifo_empty != 1) begin - spi_mem_rdata = res_fifo_rdata; - res_fifo_rd = 1; - spim_mem_ack = 1; - next_state = IDLE; - end - end - endcase -end - -/***************************************************************** -* This logic help to find any pre-fetch data available inside the response -* FIFO and if the next data read request address matches with NextPreAddr, The read -* the data from Response FIFO, else generate new request -* Note: Basic Assumption is cmd_fifo_wr & res_fifo_rd does not occur in same -* time as it's generation control through FSM -* **********************************************************/ - -always_ff @(negedge rst_n or posedge mclk) begin - if ( rst_n == 1'b0 ) begin - NextPreDVal <= 1'b0; - NextPreDCnt <= 'h0; - NextPreAddr <= 'h0; - end else if(cmd_fifo_wr) begin - NextPreDVal <= 1'b1; - NextPreDCnt <= cfg_data_cnt; - NextPreAddr <= spim_wb_addr; - end else if (res_fifo_rd) begin - if(NextPreDCnt == 4) begin - NextPreDVal <= 1'b0; - end else begin - NextPreDCnt <= NextPreDCnt-4; - NextPreAddr <= NextPreAddr+4; - end - end -end - - -endmodule
diff --git a/verilog/rtl/qspim/src/qspim_regs.sv b/verilog/rtl/qspim/src/qspim_regs.sv deleted file mode 100644 index d110ffb..0000000 --- a/verilog/rtl/qspim/src/qspim_regs.sv +++ /dev/null
@@ -1,753 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021 , Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> -// -////////////////////////////////////////////////////////////////////// -//// //// -//// SPI WishBone Register I/F Module //// -//// //// -//// This file is part of the YIFive cores project //// -//// https://github.com/dineshannayya/yifive_r0.git //// -//// http://www.opencores.org/cores/yifive/ //// -//// //// -//// Description //// -//// SPI WishBone I/F module //// -//// This block support following functionality //// -//// 1. Direct SPI Read memory support for address rang //// -//// 0x0000 to 0x0FFF_FFFF - Use full for Instruction //// -//// Data Memory fetch //// -//// 2. SPI Local Register Access //// -//// 3. Indirect register way to access SPI Memory //// -//// //// -//// To Do: //// -//// nothing //// -//// //// -//// Author(s): //// -//// - Dinesh Annayya, dinesha@opencores.org //// -//// //// -//// Revision : //// -//// V.0 - June 8, 2021 //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000 Authors and OPENCORES.ORG //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source 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 Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// - - -module qspim_regs #( parameter WB_WIDTH = 32) ( - input logic mclk , - input logic rst_n , - input logic fast_sim_mode , // Set 1 for simulation - - output logic [7:0] spi_clk_div , - output logic spi_init_done , // SPI internal Init completed - - // Status Monitoring - input logic [31:0] spi_debug , - - // Master 0 Configuration - output logic cfg_m0_fsm_reset , - output logic [3:0] cfg_m0_cs_reg , // Chip select - output logic [1:0] cfg_m0_spi_mode , // Final SPI Mode - output logic [1:0] cfg_m0_spi_switch, // SPI Mode Switching Place - output logic [3:0] cfg_m0_spi_seq , // SPI SEQUENCE - output logic [1:0] cfg_m0_addr_cnt , // SPI Addr Count - output logic [1:0] cfg_m0_dummy_cnt , // SPI Dummy Count - output logic [7:0] cfg_m0_data_cnt , // SPI Read Count - output logic [7:0] cfg_m0_cmd_reg , // SPI MEM COMMAND - output logic [7:0] cfg_m0_mode_reg , // SPI MODE REG - - output logic [3:0] cfg_m1_cs_reg , // Chip select - output logic [1:0] cfg_m1_spi_mode , // Final SPI Mode - output logic [1:0] cfg_m1_spi_switch, // SPI Mode Switching Place - - output logic [1:0] cfg_cs_early , // Amount of cycle early CS asserted - output logic [1:0] cfg_cs_late , // Amount of cycle late CS de-asserted - - // Towards Reg I/F - input logic spim_reg_req , // Reg Request - input logic [3:0] spim_reg_addr , // Reg Address - input logic spim_reg_we , // Reg Write/Read Command - input logic [3:0] spim_reg_be , // Reg Byte Enable - input logic [31:0] spim_reg_wdata , // Reg Write Data - output logic spim_reg_ack , // Read Ack - output logic [31:0] spim_reg_rdata , // Read Read Data - - // Towards Command FIFO - input logic cmd_fifo_full , // Command FIFO full - input logic cmd_fifo_empty , // Command FIFO empty - output logic cmd_fifo_wr , // Command FIFO Write - output logic [33:0] cmd_fifo_wdata , // Command FIFO WData - - // Towards Response FIFO - input logic res_fifo_full , // Response FIFO Empty - input logic res_fifo_empty , // Response FIFO Empty - output logic res_fifo_rd , // Response FIFO Read - input logic [31:0] res_fifo_rdata , // Response FIFO Data - - output logic [3:0] state - ); -//------------------------------------------------ -// Parameter Decleration -// ----------------------------------------------- -parameter SOC = 1'b1; // START of COMMAND -parameter EOC = 1'b1; // END of COMMAND -parameter NOC = 1'b0; // NORMAL COMMAND - -parameter BTYPE = 1'b0; // Count is Byte Type -parameter WTYPE = 1'b1; // Count is Word Type - -parameter CNT1 = 2'b00; // BYTE/WORD Count1 -parameter CNT2 = 2'b01; // BYTE/WORD Count2 -parameter CNT3 = 2'b10; // BYTE/WORD Count3 -parameter CNT4 = 2'b11; // BYTE/WORD Count4 - - -// Type of command -parameter NWRITE = 2'b00; // Normal Write -parameter NREAD = 2'b01; // Normal Read -parameter DWRITE = 2'b10; // Dummy Write -parameter DREAD = 2'b11; // Dummy Read - -// State Machine state -parameter FSM_IDLE = 3'b000; -parameter FSM_ADR_PHASE = 3'b001; -parameter FSM_WRITE_PHASE = 3'b010; -parameter FSM_READ_PHASE = 3'b011; -parameter FSM_READ_BUSY = 3'b100; -parameter FSM_WRITE_BUSY = 3'b101; -parameter FSM_ACK_PHASE = 3'b110; - -//---------------------------- -// Register Decoding -// --------------------------- -parameter GLBL_CTRL = 4'b0000; -parameter DMEM_CTRL1 = 4'b0001; -parameter DMEM_CTRL2 = 4'b0010; -parameter IMEM_CTRL1 = 4'b0011; -parameter IMEM_CTRL2 = 4'b0100; -parameter IMEM_ADDR = 4'b0101; -parameter IMEM_WDATA = 4'b0110; -parameter IMEM_RDATA = 4'b0111; -parameter SPI_STATUS = 4'b1000; - -// Init FSM -parameter SPI_INIT_PWUP = 3'b000; -parameter SPI_INIT_IDLE = 3'b001; -parameter SPI_INIT_CMD_WAIT = 3'b010; -parameter SPI_INIT_WREN_CMD = 3'b011; -parameter SPI_INIT_WREN_WAIT = 3'b100; -parameter SPI_INIT_WRR_CMD = 3'b101; -parameter SPI_INIT_WRR_WAIT = 3'b110; -parameter SPI_INIT_WAIT = 3'b111; - -/************************************************************* -* SPI FSM State Control -* -* OPERATION COMMAND SEQUENCE -* -* ERASE P4E(0x20) -> COMMAND + ADDRESS -* ERASE P8E(0x40) -> COMMAND + ADDRESS -* ERASE SE(0xD8) -> COMMAND + ADDRESS -* ERASE BE(0x60) -> COMMAND + ADDRESS -* ERASE BE(0xC7) -> COMMAND -* PROGRAM PP(0x02) -> COMMAND + ADDRESS + Write DATA -* PROGRAM QPP(0x32) -> COMMAND + ADDRESS + Write DATA -* READ READ(0x3) -> COMMAND + ADDRESS + READ DATA -* READ FAST_READ(0xB) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ DOR (0x3B) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ QOR (0x6B) -> COMMAND + ADDRESS + DUMMY + READ DATA -* READ DIOR (0xBB) -> COMMAND + ADDRESS + MODE + READ DATA -* READ QIOR (0xEB) -> COMMAND + ADDRESS + MODE + DUMMY + READ DATA -* READ RDID (0x9F) -> COMMAND + READ DATA -* READ READ_ID (0x90) -> COMMAND + ADDRESS + READ DATA -* WRITE WREN(0x6) -> COMMAND -* WRITE WRDI -> COMMAND -* STATUS RDSR(0x05) -> COMMAND + READ DATA -* STATUS RCR(0x35) -> COMMAND + READ DATA -* CONFIG WRR(0x01) -> COMMAND + WRITE DATA -* CONFIG CLSR(0x30) -> COMMAND -* Power Saving DP(0xB9) -> COMMAND -* Power Saving RES(0xAB) -> COMMAND + READ DATA -* OTP OTPP(0x42) -> COMMAND + ADDR+ WRITE DATA -* OTP OTPR(0x4B) -> COMMAND + ADDR + DUMMY + READ DATA -* ********************************************************************/ -parameter P_FSM_C = 4'b0000; // Command Phase Only -parameter P_FSM_CW = 4'b0001; // Command + Write DATA Phase Only -parameter P_FSM_CA = 4'b0010; // Command -> Address Phase Only - -parameter P_FSM_CAR = 4'b0011; // Command -> Address -> Read Data -parameter P_FSM_CADR = 4'b0100; // Command -> Address -> Dummy -> Read Data -parameter P_FSM_CAMR = 4'b0101; // Command -> Address -> Mode -> Read Data -parameter P_FSM_CAMDR = 4'b0110; // Command -> Address -> Mode -> Dummy -> Read Data - -parameter P_FSM_CAW = 4'b0111; // Command -> Address ->Write Data -parameter P_FSM_CADW = 4'b1000; // Command -> Address -> DUMMY + Write Data - -parameter P_FSM_CDR = 4'b1001; // COMMAND -> DUMMY -> READ -parameter P_FSM_CDW = 4'b1010; // COMMAND -> DUMMY -> WRITE -parameter P_FSM_CR = 4'b1011; // COMMAND -> READ -//--------------------------------------------------------- - parameter P_CS0 = 4'b0001; - parameter P_CS1 = 4'b0010; - parameter P_CS2 = 4'b0100; - parameter P_CS3 = 4'b1000; - - parameter P_SINGLE = 2'b00; - parameter P_DOUBLE = 2'b01; - parameter P_QUAD = 2'b10; - - parameter P_MODE_SWITCH_IDLE = 2'b00; - parameter P_MODE_SWITCH_AT_ADDR = 2'b01; - parameter P_MODE_SWITCH_AT_DATA = 2'b10; - - parameter P_QOR = 8'h6B; - parameter P_QIOR = 8'hEB; - parameter P_RES = 8'hAB; - parameter P_WEN = 8'h06; - parameter P_WRR = 8'h01; - - parameter P_8BIT = 2'b00; - parameter P_16BIT = 2'b01; - parameter P_24BIT = 2'b10; - parameter P_32BIT = 2'b11; -//--------------------------------------------------------- -// Variable declartion -// ------------------------------------------------------- -logic [2:0] spi_init_state ; -logic spim_reg_req_f ; - -logic [1:0] cfg_m1_fsm_reset ; -logic [3:0] cfg_m1_spi_seq ; // SPI SEQUENCE -logic [1:0] cfg_m1_addr_cnt ; // SPI Addr Count -logic [1:0] cfg_m1_dummy_cnt ; // SPI Dummy Count -logic [7:0] cfg_m1_data_cnt ; // SPI Read Count -logic [7:0] cfg_m1_cmd_reg ; // SPI MEM COMMAND -logic [7:0] cfg_m1_mode_reg ; // SPI MODE REG -logic [31:0] cfg_m1_addr ; -logic [31:0] cfg_m1_wdata ; -logic [31:0] cfg_m1_rdata ; -logic cfg_m1_wrdy ; -logic cfg_m1_req ; - -logic [31:0] reg_rdata ; - - -logic [5:0] cur_cnt ; -logic [5:0] next_cnt ; -logic [3:0] next_state ; - - -logic [31:0] spim_m1_rdata ; -logic spim_m1_ack ; -logic spim_m1_rrdy ; -logic spim_m1_wrdy ; -logic [9:0] spi_delay_cnt ; -logic spim_fifo_rdata_req ; -logic spim_fifo_wdata_req ; - - -//---------------------------------------------- -// Consolidated Register Ack handling -// 1. Handles Normal Register Read -// 2. Indirect Memory Write -// 3. Indirect Memory Read -//---------------------------------------------- -// -assign spim_fifo_rdata_req = spim_reg_req && spim_reg_we == 0 && (spim_reg_addr== IMEM_RDATA); -assign spim_fifo_wdata_req = spim_reg_req && spim_reg_we == 1 && (spim_reg_addr== IMEM_WDATA); - -always_ff @(negedge rst_n or posedge mclk) begin - if ( rst_n == 1'b0 ) begin - spim_reg_ack <= 1'b0; - spim_reg_rdata <= 'h0; - end else begin - if(spi_init_done && spim_reg_ack == 0) begin - if (spim_fifo_wdata_req && (spim_m1_wrdy == 1)) begin // Indirect Memory Write - // If FIFO Write DATA case, Make sure that there no previous pending - // need to processed - spim_reg_ack <= 1'b1; - end else if (spim_reg_req && spim_reg_we && (spim_reg_addr != IMEM_WDATA)) begin // Indirect memory Write - spim_reg_ack <= 1'b1; - end else if (spim_fifo_rdata_req && (spim_m1_rrdy == 1)) begin // Indirect mem Read - // If FIFO Read DATA case, Make sure that there Data is read from - // External SPI Memory - spim_reg_ack <= 1'b1; - spim_reg_rdata <= reg_rdata; - end else if (spim_reg_req && spim_reg_we == 0 && (spim_reg_addr != IMEM_RDATA)) begin // Normal Read - // Read other than FIFO Read Data case - spim_reg_ack <= 1'b1; - spim_reg_rdata <= reg_rdata; - end - end else begin - spim_reg_ack <= 1'b0; - end - end -end - - //--------------------------------------------- - // Manges the initial Config Phase of SPI Memory - // 1. Power Up Command - RES(0xAB) - // 2. Write Enable Command - WEN (0x06) - // 3. WRITE CONFIG Reg - WRR (0x01) - Set Qaud Mode - // -------------------------------------------- - - logic [9:0] cfg_exit_cnt ; - assign cfg_exit_cnt = (fast_sim_mode) ? 100: 1000; - - integer byte_index; - always_ff @(negedge rst_n or posedge mclk) begin - if ( rst_n == 1'b0 ) begin - cfg_m0_fsm_reset <= 'h0; - cfg_m0_cs_reg <= P_CS0; - cfg_m0_spi_mode <= P_QUAD; - cfg_m0_spi_switch <= P_MODE_SWITCH_AT_ADDR; - cfg_m0_cmd_reg <= P_QIOR; - cfg_m0_mode_reg <= 'h0; - cfg_m0_spi_seq[3:0] <= P_FSM_CAMDR; - cfg_m0_addr_cnt[1:0] <= P_24BIT; - cfg_m0_dummy_cnt[1:0] <= P_16BIT; - cfg_m0_data_cnt[7:0] <= 8'h20; // 32 Byte - - cfg_m1_fsm_reset <= 'h0; - cfg_m1_cs_reg <= P_CS0; - cfg_m1_spi_mode <= P_QUAD; - cfg_m1_spi_switch <= P_MODE_SWITCH_AT_DATA; - cfg_m1_cmd_reg <= P_QOR; - cfg_m1_mode_reg <= 'h0; - cfg_m1_spi_seq[3:0] <= P_FSM_CADR; - cfg_m1_addr_cnt[1:0] <= P_24BIT; - cfg_m1_dummy_cnt[1:0] <= P_8BIT; - cfg_m1_data_cnt[7:0] <= 0; - cfg_m1_req <= 0; - cfg_m1_wrdy <= 1'b0; - cfg_m1_wdata <= 'h0; // Not Used - - cfg_cs_early <= 'h1; - cfg_cs_late <= 'h1; - spi_clk_div <= 'h2; - - spi_init_done <= 'h0; - spi_delay_cnt <= 'h0; - spim_reg_req_f <= 1'b0; - spi_init_state <= SPI_INIT_PWUP; - end else begin - spim_reg_req_f <= spim_reg_req; // Needed for finding Req Edge - if (spi_init_done == 0) begin - case(spi_init_state) - - //---------------------------------------------- - // SPI MEMORY Need minimum 5Us after power up - // With 100Mhz, 10ns translated to 500 cycle - // We are waiting 1000 cycle - // --------------------------------------------- - SPI_INIT_PWUP:begin - if(spi_delay_cnt == cfg_exit_cnt) begin - spi_init_state <= SPI_INIT_IDLE; - end else begin - spi_delay_cnt <= spi_delay_cnt+1; - end - end - - SPI_INIT_IDLE: - begin - cfg_m1_cs_reg <= P_CS0; - cfg_m1_spi_mode <= P_SINGLE; - cfg_m1_spi_seq[3:0] <= P_FSM_C; - cfg_m1_spi_switch <= '0; - cfg_m1_cmd_reg <= P_RES; - cfg_m1_mode_reg <= 'h0; // Not Used - cfg_m1_addr_cnt[1:0] <= 'h0; // Not Used - cfg_m1_dummy_cnt[1:0]<= 'h0; // Not Used - cfg_m1_data_cnt[7:0] <= 'h0; // Not Used - cfg_m1_addr <= 'h0; // Not Used - cfg_m1_wdata <= 'h0; // Not Used - cfg_m1_req <= 'h1; - spi_init_state <= SPI_INIT_CMD_WAIT; - end - SPI_INIT_CMD_WAIT: - begin - if(spim_m1_ack) begin - cfg_m1_req <= 1'b0; - spi_init_state <= SPI_INIT_WREN_CMD; - end - end - SPI_INIT_WREN_CMD: - begin - cfg_m1_cs_reg <= P_CS0; - cfg_m1_spi_mode <= P_SINGLE; - cfg_m1_spi_seq[3:0] <= P_FSM_C; - cfg_m1_spi_switch <= '0; - cfg_m1_cmd_reg <= P_WEN; - cfg_m1_mode_reg <= 'h0; // Not Used - cfg_m1_addr_cnt[1:0] <= 'h0; // Not Used - cfg_m1_dummy_cnt[1:0]<= 'h0; // Not Used - cfg_m1_data_cnt[7:0] <= 'h0; // Not Used - cfg_m1_addr <= 'h0; // Not Used - cfg_m1_wdata <= 'h0; // Not Used - cfg_m1_req <= 'h1; - spi_init_state <= SPI_INIT_WREN_WAIT; - end - SPI_INIT_WREN_WAIT: - begin - if(spim_m1_ack) begin - cfg_m1_req <= 1'b0; - spi_init_state <= SPI_INIT_WRR_CMD; - end - end - SPI_INIT_WRR_CMD: - begin - cfg_m1_cs_reg <= P_CS0; - cfg_m1_spi_mode <= P_SINGLE; - cfg_m1_spi_seq[3:0] <= P_FSM_CW; - cfg_m1_spi_switch <= '0; - cfg_m1_cmd_reg <= P_WRR; - cfg_m1_mode_reg <= 'h0; - cfg_m1_addr_cnt[1:0] <= 'h0; - cfg_m1_dummy_cnt[1:0]<= 'h0; - cfg_m1_data_cnt[7:0] <= 'h2; // 2 Bytes - cfg_m1_addr <= 'h0; - cfg_m1_wrdy <= 1'b1; - cfg_m1_wdata <= {16'h0,8'h2,8'h0}; // <<cr1[7:0]><sr1[7:0]>> cr1[1] = 1 indicate quad mode cr1[7:6]=3 - cfg_m1_req <= 'h1; - spi_init_state <= SPI_INIT_WRR_WAIT; - end - SPI_INIT_WRR_WAIT: - begin - if(spim_m1_ack) begin - spi_delay_cnt <= 'h0; - cfg_m1_wrdy <= 1'b0; - cfg_m1_req <= 1'b0; - spi_init_state <= SPI_INIT_WAIT; - end - end - SPI_INIT_WAIT: - begin // SPI MEMORY need 5us after WRR Command - if(spi_delay_cnt == cfg_exit_cnt) begin - spi_init_done <= 'h1; - end else begin - spi_delay_cnt <= spi_delay_cnt+1; - end - end - endcase - end else if (spim_reg_req && spim_reg_we && spi_init_done ) - begin - case(spim_reg_addr) - GLBL_CTRL: begin - if ( spim_reg_be[0] == 1 ) begin - cfg_cs_early <= spim_reg_wdata[1:0]; - cfg_cs_late <= spim_reg_wdata[3:2]; - end - if ( spim_reg_be[1] == 1 ) begin - spi_clk_div <= spim_reg_wdata[15:8]; - end - end - DMEM_CTRL1: begin // This register control Direct Memory Access Type - if ( spim_reg_be[0] == 1 ) begin - cfg_m0_cs_reg <= spim_reg_wdata[3:0]; // Chip Select for Memory Interface - cfg_m0_spi_mode <= spim_reg_wdata[5:4]; // SPI Mode, 0 - Normal, 1- Double, 2 - Qard, 3 - QDDR - cfg_m0_spi_switch<= spim_reg_wdata[7:6]; // Phase where to switch the SPI Mode - end - if ( spim_reg_be[1] == 1 ) begin - cfg_m0_fsm_reset <= spim_reg_wdata[8]; - end - end - DMEM_CTRL2: begin // This register control Direct Memory Access Type - if ( spim_reg_be[0] == 1 ) begin - cfg_m0_cmd_reg <= spim_reg_wdata[7:0]; - end - if ( spim_reg_be[1] == 1 ) begin - cfg_m0_mode_reg <= spim_reg_wdata[15:8]; - end - if ( spim_reg_be[2] == 1 ) begin - cfg_m0_spi_seq[3:0] <= spim_reg_wdata[19:16]; - cfg_m0_addr_cnt[1:0] <= spim_reg_wdata[21:20]; - cfg_m0_dummy_cnt[1:0]<= spim_reg_wdata[23:22]; - end - if ( spim_reg_be[3] == 1 ) begin - cfg_m0_data_cnt[7:0] <= spim_reg_wdata[31:24]; - end - end - IMEM_CTRL1: begin - if ( spim_reg_be[0] == 1 ) begin - cfg_m1_cs_reg <= spim_reg_wdata[3:0]; // Chip Select for Memory Interface - cfg_m1_spi_mode <= spim_reg_wdata[5:4]; // SPI Mode, 0 - Normal, 1- Double, 2 - Qard - cfg_m1_spi_switch<= spim_reg_wdata[7:6]; // Phase where to switch the SPI Mode - end - if ( spim_reg_be[0] == 1 ) begin - cfg_m1_fsm_reset <= spim_reg_wdata[8]; - end - end - IMEM_CTRL2: begin // This register control Direct Memory Access Type - if ( spim_reg_be[0] == 1 ) begin - cfg_m1_cmd_reg <= spim_reg_wdata[7:0]; - end - if ( spim_reg_be[1] == 1 ) begin - cfg_m1_mode_reg <= spim_reg_wdata[15:8]; - end - if ( spim_reg_be[2] == 1 ) begin - cfg_m1_spi_seq[3:0] <= spim_reg_wdata[19:16]; - cfg_m1_addr_cnt[1:0] <= spim_reg_wdata[21:20]; - cfg_m1_dummy_cnt[1:0]<= spim_reg_wdata[23:22]; - end - if ( spim_reg_be[3] == 1 ) begin - cfg_m1_data_cnt[7:0] <= spim_reg_wdata[31:24]; - end - end - IMEM_ADDR: begin - for (byte_index = 0; byte_index < 4; byte_index = byte_index+1 ) - if ( spim_reg_be[byte_index] == 1 ) - cfg_m1_addr[byte_index*8 +: 8] <= spim_reg_wdata[(byte_index*8) +: 8]; - end - endcase - end - end - end - - - - // implement slave model register read mux - always_comb - begin - reg_rdata = '0; - if(spim_reg_req) begin - case(spim_reg_addr) - GLBL_CTRL: reg_rdata[31:0] = {16'h0,spi_clk_div,4'h0,cfg_cs_late,cfg_cs_early}; - DMEM_CTRL1: reg_rdata[31:0] = {23'h0,cfg_m0_fsm_reset,cfg_m0_spi_switch,cfg_m0_spi_mode,cfg_m0_cs_reg}; - DMEM_CTRL2: reg_rdata[31:0] = {cfg_m0_data_cnt,cfg_m0_dummy_cnt,cfg_m0_addr_cnt,cfg_m0_spi_seq,cfg_m0_mode_reg,cfg_m0_cmd_reg}; - IMEM_CTRL1: reg_rdata[31:0] = {23'h0, cfg_m1_fsm_reset,cfg_m1_spi_switch,cfg_m1_spi_mode,cfg_m1_cs_reg}; - IMEM_CTRL2: reg_rdata[31:0] = {cfg_m1_data_cnt,cfg_m1_dummy_cnt,cfg_m1_addr_cnt,cfg_m1_spi_seq,cfg_m1_mode_reg,cfg_m1_cmd_reg}; - IMEM_ADDR: reg_rdata[31:0] = cfg_m1_addr; - IMEM_WDATA: reg_rdata[31:0] = cfg_m1_wdata; - IMEM_RDATA: reg_rdata[31:0] = cfg_m1_rdata; - SPI_STATUS: reg_rdata[31:0] = spi_debug; - endcase - end - end - -// FSM - -always_ff @(negedge rst_n or posedge mclk) begin - if ( rst_n == 1'b0 ) begin - cur_cnt <= 'h0; - state <= FSM_IDLE; - end else begin - if(cfg_m1_fsm_reset) begin - cur_cnt <= 'h0; - state <= FSM_IDLE; - end else begin - cur_cnt <= next_cnt; - state <= next_state; - end - end -end - -/*********************************************************************************** -* This block interface with WishBone Request and Write Command & Read Response FIFO -* **********************************************************************************/ - -logic [7:0] cfg_data_cnt; -logic [31:0] spim_fifo_wdata; -logic spim_fifo_req; -assign cfg_data_cnt = cfg_m1_data_cnt-1; - -assign spim_fifo_req = cfg_m1_req || spim_fifo_rdata_req || spim_fifo_wdata_req; - -assign spim_fifo_wdata = (cfg_m1_req) ? cfg_m1_wdata : spim_reg_wdata; - -always_comb -begin - cmd_fifo_wr = '0; - cmd_fifo_wdata = '0; - - res_fifo_rd = 0; - spim_m1_rdata = '0; - - spim_m1_ack = 0; - spim_m1_rrdy = 0; - next_cnt = cur_cnt; - next_state = state; - spim_m1_rrdy = 0; - spim_m1_wrdy = 0; - cfg_m1_rdata = 0; - - case(state) - FSM_IDLE: begin - next_cnt = 0; - if(spim_fifo_req && cmd_fifo_empty) begin - case(cfg_m1_spi_seq) - P_FSM_C: begin - cmd_fifo_wdata = {SOC,EOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0], - cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0], - cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]}; - spim_m1_wrdy = 1; - next_state = FSM_ACK_PHASE; - end - P_FSM_CW, - P_FSM_CDW: - begin - cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0], - cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0], - cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]}; - next_state = FSM_WRITE_PHASE; - end - P_FSM_CA, - P_FSM_CAR, - P_FSM_CADR, - P_FSM_CAMR, - P_FSM_CAMDR, - P_FSM_CAW, - P_FSM_CADW: - begin - cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0], - cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0], - cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]}; - next_state = FSM_ADR_PHASE; - end - P_FSM_CDR, - P_FSM_CR: - begin - cmd_fifo_wdata = {SOC,EOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0], - cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0], - cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]}; - next_state = FSM_READ_PHASE; - end - - - endcase - cmd_fifo_wr = 1; - end - end - // ADDRESS PHASE - FSM_ADR_PHASE: begin - if(!cmd_fifo_full) begin - case(cfg_m1_spi_seq) - P_FSM_CA: // COMMAND + ADDRESS PHASE - begin - cmd_fifo_wdata = {NOC,EOC,cfg_m1_addr[31:0]}; - spim_m1_wrdy = 1; - next_state = FSM_ACK_PHASE; - end - P_FSM_CAR, // COMMAND + ADDRESS + READ PHASE - P_FSM_CADR, // COMMAND + ADDRESS + DUMMY + READ PHASE - P_FSM_CAMR, // COMMAND + ADDRESS + MODE + READ PHASE - P_FSM_CAMDR: // COMMAND + ADDRESS + MODE + DUMMY + READ PHASE - begin - cmd_fifo_wdata = {NOC,EOC,cfg_m1_addr[31:0]}; - next_cnt = 'h0; - next_state = FSM_READ_PHASE; - end - - P_FSM_CAW, - P_FSM_CADW: - begin - cmd_fifo_wdata = {NOC,NOC,cfg_m1_addr[31:0]}; - next_cnt = 'h0; - next_state = FSM_WRITE_PHASE; - end - endcase - cmd_fifo_wr = 1; - end - end - - //---------------------------------------------------------- - // Check Resonse FIFO is not empty then read the data from response fifo - // --------------------------------------------------------- - FSM_READ_PHASE: begin - if(res_fifo_empty != 1 && spim_fifo_rdata_req) begin - spim_m1_rrdy = 1; - cfg_m1_rdata = res_fifo_rdata; - res_fifo_rd = 1; - if(cfg_data_cnt[7:2] == cur_cnt) begin - next_state = FSM_ACK_PHASE; - end else begin - next_state = FSM_READ_BUSY; - next_cnt = cur_cnt+1; - end - end - end - //---------------------------------------------- - // Wait for Previous Read Data Read - // --------------------------------------------- - FSM_READ_BUSY: begin - spim_m1_rrdy = 0; - if(spim_fifo_rdata_req == 0) begin - next_state = FSM_READ_PHASE; - end - end - - //---------------------------------------------------------- - // Check command FIFO is not full and Write Data is available - // --------------------------------------------------------- - FSM_WRITE_PHASE: begin - if(cmd_fifo_full != 1 && spim_fifo_req) begin - // If this a single word config cycle or - // in crrent spim_fifo_wr request - spim_m1_wrdy = 1; - if(cfg_data_cnt[7:2] == cur_cnt) begin - cmd_fifo_wdata = {NOC,EOC,spim_fifo_wdata[31:0]}; - next_state = FSM_ACK_PHASE; - end else begin - cmd_fifo_wdata = {NOC,NOC,spim_fifo_wdata[31:0]}; - next_state = FSM_WRITE_BUSY; - next_cnt = cur_cnt+1; - end - cmd_fifo_wr = 1; - end - end - //---------------------------------------------- - // Wait for NEXT Data Ready - // --------------------------------------------- - FSM_WRITE_BUSY: begin - spim_m1_wrdy = 0; - if(spim_fifo_wdata_req == 0) begin - next_state = FSM_WRITE_PHASE; - end - end - - FSM_ACK_PHASE: begin - spim_m1_ack = 1; - next_state = FSM_IDLE; - end - - endcase - - -end - -endmodule
diff --git a/verilog/rtl/qspim/src/qspim_rx.sv b/verilog/rtl/qspim/src/qspim_rx.sv deleted file mode 100644 index 097ae59..0000000 --- a/verilog/rtl/qspim/src/qspim_rx.sv +++ /dev/null
@@ -1,229 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021 , Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> -// -////////////////////////////////////////////////////////////////////// -//// //// -//// SPI RX Module //// -//// //// -//// This file is part of the YIFive cores project //// -//// https://github.com/dineshannayya/yifive_r0.git //// -//// http://www.opencores.org/cores/yifive/ //// -//// //// -//// Description //// -//// SPI RX module //// -//// //// -//// To Do: //// -//// nothing //// -//// //// -//// Author(s): //// -//// - Dinesh Annayya, dinesha@opencores.org //// -//// //// -//// Revision : //// -//// V.0 - June 8, 2021 //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000 Authors and OPENCORES.ORG //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source 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 Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// - - -module qspim_rx #( - parameter ENDIEAN = 0 // 0 - Little, 1 - Big endian, since RISV is Little indian default set 0 - ) -( - input logic clk, - input logic rstn, - input logic flush, - input logic en, - input logic rx_edge, - output logic rx_done, - input logic sdi0, - input logic sdi1, - input logic sdi2, - input logic sdi3, - input logic [1:0] s_spi_mode, - input logic [15:0] counter_in, - input logic counter_in_upd, - output logic [31:0] data, - input logic data_ready, - output logic data_valid, - output logic clk_en_o -); -//------------------------------------------------------ -// Parameter Decleration -// ----------------------------------------------------- - parameter P_SINGLE = 2'b00; - parameter P_DOUBLE = 2'b01; - parameter P_QUAD = 2'b10; - parameter P_QDDR = 2'b11; - -//------------------------------------------------------ -// Variable Decleration -// ----------------------------------------------------- - - logic [31:0] data_int; - logic [31:0] data_int_next; - logic [15:0] counter; - logic [15:0] counter_trgt; - logic [15:0] counter_next; - logic reg_done; - logic data_valid_i; - logic qddr_rx_en; - enum logic [1:0] { IDLE, RECEIVE, WAIT_FIFO, WAIT_FIFO_DONE } rx_CS, rx_NS; - - - assign reg_done = (s_spi_mode == P_SINGLE && (counter[4:0] == 5'b11111)) || - (s_spi_mode == P_DOUBLE && (counter[3:0] == 4'b1111)) || - (s_spi_mode == P_QUAD && (counter[2:0] == 3'b111)) || - (s_spi_mode == P_QDDR && (counter[2:0] == 3'b111)); - - - - always_comb - begin - rx_NS = rx_CS; - data_int_next = data_int; - data_valid_i = 1'b0; - counter_next = counter; - - case (rx_CS) - IDLE: begin - - // check first if there is available space instead of later - if (en) begin - rx_NS = RECEIVE; - end - end - - RECEIVE: begin - - if (rx_edge || qddr_rx_en) begin - counter_next = counter + 1; - if ((s_spi_mode == P_QUAD ) || (s_spi_mode == P_QDDR )) - data_int_next = {data_int[27:0],sdi3,sdi2,sdi1,sdi0}; - else if (s_spi_mode == P_DOUBLE ) - data_int_next = {data_int[29:0],sdi1,sdi0}; - else - data_int_next = {data_int[30:0],sdi1}; - - if (rx_done) begin - counter_next = 0; - if (data_ready) begin - data_valid_i = 1'b1; - rx_NS = IDLE; - end else - rx_NS = WAIT_FIFO_DONE; - end else if (reg_done) begin - if (data_ready) begin - data_valid_i = 1'b1; - end else begin - // no space in the FIFO, wait for free space - rx_NS = WAIT_FIFO; - end - end - end - end - - WAIT_FIFO_DONE: begin - if (data_ready) begin - data_valid_i = 1'b1; - rx_NS = IDLE; - end - end - - WAIT_FIFO: begin - if (data_ready) begin - data_valid_i = 1'b1; - rx_NS = RECEIVE; - end - end - endcase - end - - - always_ff @(posedge clk, negedge rstn) - begin - if (rstn == 0) - begin - counter <= 0; - counter_trgt <= 'h8; - data_int <= '0; - rx_done <= '0; - clk_en_o <= '0; - data <= 'b0; - data_valid <= 1'b0; - qddr_rx_en <= '0; - rx_CS <= IDLE; - end else if(flush && rx_edge) begin - counter <= 0; - counter_trgt <= 'h8; - data_int <= '0; - rx_done <= '0; - clk_en_o <= '0; - data <= 'b0; - data_valid <= 1'b0; - qddr_rx_en <= 0; - rx_CS <= IDLE; - end else begin - // Enable qddr rx after first rx edge - if(en && rx_edge && (rx_CS == RECEIVE) && (s_spi_mode ==P_QDDR)) begin - qddr_rx_en <= 1; - end else if(!en || rx_done) begin - qddr_rx_en <= 0; - end - - data_valid <= data_valid_i; - data <= (ENDIEAN) ? data_int_next : {data_int_next[7:0],data_int_next[15:8],data_int_next[23:16],data_int_next[31:24]}; - clk_en_o <= (rx_NS == RECEIVE); - if (rx_edge || qddr_rx_en) begin - counter <= counter_next; - data_int <= data_int_next; - rx_CS <= rx_NS; - rx_done <= (counter_next == (counter_trgt-1)) && (rx_NS == RECEIVE); - clk_en_o <= (rx_NS == RECEIVE); - end - if (en && counter_in_upd) begin - counter_trgt <= (s_spi_mode ==P_QDDR ) ? {2'b00,counter_in[15:2]} : - (s_spi_mode ==P_QUAD ) ? {2'b00,counter_in[15:2]} : - (s_spi_mode ==P_DOUBLE ) ? {1'b0,counter_in[15:1]} : counter_in; - end - end - end - -endmodule
diff --git a/verilog/rtl/qspim/src/qspim_top.sv b/verilog/rtl/qspim/src/qspim_top.sv deleted file mode 100644 index a7c3a4b..0000000 --- a/verilog/rtl/qspim/src/qspim_top.sv +++ /dev/null
@@ -1,521 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021 , Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> -// -////////////////////////////////////////////////////////////////////// -//// //// -//// SPI Master Top Module //// -//// //// -//// This file is part of the YIFive cores project //// -//// https://github.com/dineshannayya/yifive_r0.git //// -//// http://www.opencores.org/cores/yifive/ //// -//// //// -//// Description //// -//// SPI Master Top module //// -//// There are two seperate Data path managed here //// -//// with seperate command and response memory //// -//// Master-0 : This is targetted for CORE IMEM request //// -//// and expect only Read access //// -//// Master-1: This is targetted to CORE DMEM or //// -//// Indirect Memory access, Both Write and Read //// -//// accesss are supported. //// -//// Upto 255 Byte Read/Write Burst supported //// -//// Limitation: //// -//// 1. Write/Read FIFO Abort case not managed M1 port, //// -//// expect user to clearly close the busrt request //// -//// 2. Wishbone Request abort not yet supported. //// -//// 3. Write access through M0 Port not supported //// -//// 4. When Pre fetch feature used and both port m0 and //// -//// m1 used, user need to make sure that data pre fetch//// -//// count is withing 8DW, less Read path can hang due //// -//// to response FIFO full from one master port //// -//// //// -//// To Do: //// -//// 1. Add support for WishBone request timout //// -//// 2. Add Pre-fetch feature for M0 Port //// -//// //// -//// Author(s): //// -//// - Dinesh Annayya, dinesha@opencores.org //// -//// //// -//// Revision : //// -//// V.0 - June 8, 2021 //// -//// V.1 - June 25, 2021 //// -//// Pad logic is brought inside the block to avoid //// -//// logic at digital core level for caravel project //// -//// V.2 - July 6, 2021 //// -//// Added Hold fix cell for SPI data out signal to //// -//// met interface hold //// -//// V.3 - July 13, 2021 //// -//// Data Prefetch feature added in M0 port, If Only //// -//// M0 Read used, then Prefetch read can be 255 Byte, //// -//// But if the Both M0 and M1 read access enabled, //// -//// then user need to make sure that M0 Prefetch is //// -//// with in 8DW or 32 Byte, else there is chance //// -//// data path can hang due to response FIFO full due //// -//// to partial reading of data //// -//// V.4 - July 26, 2021 //// -//// QDDR (0xED) supported is added //// -//// V.5 - Nov 6, 2021 //// -//// Clock Skew Moves inside the block //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000 Authors and OPENCORES.ORG //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source 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 Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// - - - -module qspim_top -#( parameter WB_WIDTH = 32) -( -`ifdef USE_POWER_PINS - input logic vccd1, // User area 1 1.8V supply - input logic vssd1, // User area 1 digital ground -`endif - input logic mclk, - input logic rst_n, - - input logic [3:0] cfg_cska_sp_co, // spi clock skew adjust - input logic [3:0] cfg_cska_spi, - input logic wbd_clk_int, - output logic wbd_clk_spi, - - input logic wbd_stb_i, // strobe/request - input logic [WB_WIDTH-1:0] wbd_adr_i, // address - input logic wbd_we_i, // write - input logic [WB_WIDTH-1:0] wbd_dat_i, // data output - input logic [3:0] wbd_sel_i, // byte enable - output logic [WB_WIDTH-1:0] wbd_dat_o, // data input - output logic wbd_ack_o, // acknowlegement - output logic wbd_err_o, // error - - output logic [31:0] spi_debug, - - // PAD I/f - input logic [3:0] spi_sdi, - output logic spi_clk, - output logic spi_csn0,// No hold fix for CS#, as it asserted much eariler than SPI clock - output logic [3:0] spi_sdo, - output logic [3:0] spi_oen -); - - - - logic [7:0] spi_clk_div ; - - // Master 0 Configuration - logic cfg_m0_fsm_reset ; - logic [3:0] cfg_m0_cs_reg ; // Chip select - logic [1:0] cfg_m0_spi_mode ; // Final SPI Mode - logic [1:0] cfg_m0_spi_switch; // SPI Mode Switching Place - logic [3:0] cfg_m0_spi_seq ; // SPI SEQUENCE - logic [1:0] cfg_m0_addr_cnt ; // SPI Addr Count - logic [1:0] cfg_m0_dummy_cnt ; // SPI Dummy Count - logic [7:0] cfg_m0_data_cnt ; // SPI Read Count - logic [7:0] cfg_m0_cmd_reg ; // SPI MEM COMMAND - logic [7:0] cfg_m0_mode_reg ; // SPI MODE REG - - logic [3:0] cfg_m1_cs_reg ; // Chip select - logic [1:0] cfg_m1_spi_mode ; // Final SPI Mode - logic [1:0] cfg_m1_spi_switch; // SPI Mode Switching Place - - logic [1:0] cfg_cs_early ; // Amount of cycle early CS asserted - logic [1:0] cfg_cs_late ; // Amount of cycle late CS de-asserted - - // Towards Reg I/F - logic spim_reg_req ; // Reg Request - logic [3:0] spim_reg_addr ; // Reg Address - logic spim_reg_we ; // Reg Write/Read Command - logic [3:0] spim_reg_be ; // Reg Byte Enable - logic [31:0] spim_reg_wdata ; // Reg Write Data - logic spim_reg_ack ; // Read Ack - logic [31:0] spim_reg_rdata ; // Read Read Data - - // Towards m0 Command FIFO - logic m0_cmd_fifo_full ; // Command FIFO full - logic m0_cmd_fifo_empty ; // Command FIFO empty - logic m0_cmd_fifo_wr ; // Command FIFO Write - logic m0_cmd_fifo_rd ; // Command FIFO read - logic [33:0] m0_cmd_fifo_wdata ; // Command FIFO WData - logic [33:0] m0_cmd_fifo_rdata ; // Command FIFO RData - - // Towards m0 Response FIFO - logic m0_res_fifo_full ; // Response FIFO Empty - logic m0_res_fifo_empty ; // Response FIFO Empty - logic m0_res_fifo_wr ; // Response FIFO Write - logic m0_res_fifo_rd ; // Response FIFO Read - logic [31:0] m0_res_fifo_wdata ; // Response FIFO WData - logic [31:0] m0_res_fifo_rdata ; // Response FIFO RData - - // Towards m1 Command FIFO - logic m1_cmd_fifo_full ; // Command FIFO full - logic m1_cmd_fifo_empty ; // Command FIFO empty - logic m1_cmd_fifo_wr ; // Command FIFO Write - logic m1_cmd_fifo_rd ; // Command FIFO Write - logic [33:0] m1_cmd_fifo_wdata ; // Command FIFO WData - logic [33:0] m1_cmd_fifo_rdata ; // Command FIFO RData - - // Towards m0 Response FIFO - logic m1_res_fifo_full ; // Response FIFO Empty - logic m1_res_fifo_empty ; // Response FIFO Empty - logic m1_res_fifo_wr ; // Response FIFO Read - logic m1_res_fifo_rd ; // Response FIFO Read - logic [31:0] m1_res_fifo_wdata ; // Response FIFO WData - logic [31:0] m1_res_fifo_rdata ; // Response FIFO RData - - logic m0_res_fifo_flush ; // m0 response fifo flush - logic m1_res_fifo_flush ; // m0 response fifo flush - -//----------------------------------------------------- -// SPI Debug monitoring -// ---------------------------------------------------- - logic [8:0] spi_ctrl_status ; - logic [3:0] m0_state ; - logic [3:0] m1_state ; - logic [3:0] ctrl_state ; - - - assign spi_debug = {m0_res_fifo_flush,m1_res_fifo_flush,spi_init_done, - m0_cmd_fifo_full,m0_cmd_fifo_empty,m0_res_fifo_full,m0_res_fifo_empty, - m1_cmd_fifo_full,m1_cmd_fifo_empty,m1_res_fifo_full,m1_res_fifo_empty, - ctrl_state[3:0], m0_state[3:0],m1_state[3:0],spi_ctrl_status[8:0]}; - -//------------------------------------------------------- -// SPI Interface moved inside to support carvel IO pad -// ------------------------------------------------------- - -logic spi_csn1; -logic spi_csn2; -logic spi_csn3; -logic [1:0] spi_mode; -logic spi_en_tx; -logic spi_init_done; -logic [3:0] spi_sdo_int; -logic spi_clk_int; -logic spi_sdo0_dl; -logic spi_sdo1_dl; -logic spi_sdo2_dl; -logic spi_sdo3_dl; -logic rst_ss_n; - - - -// ADDing Delay cells for Interface hold fix -wire spi_sdo0_d1,spi_sdo0_d2; -ctech_delay_buf u_delay1_sdio0 (.X(spi_sdo0_d1),.A(spi_sdo_int[0])); -ctech_delay_buf u_delay2_sdio0 (.X(spi_sdo0_d2),.A(spi_sdo0_d1)); -ctech_buf u_buf_sdio0 (.X(spi_sdo[0]),.A(spi_sdo0_d2)); - -wire spi_sdo1_d1,spi_sdo1_d2; -ctech_delay_buf u_delay1_sdio1 (.X(spi_sdo1_d1),.A(spi_sdo_int[1])); -ctech_delay_buf u_delay2_sdio1 (.X(spi_sdo1_d2),.A(spi_sdo1_d1)); -ctech_buf u_buf_sdio1 (.X(spi_sdo[1]),.A(spi_sdo1_d2)); - -wire spi_sdo2_d1,spi_sdo2_d2; -ctech_delay_buf u_delay1_sdio2 (.X(spi_sdo2_d1),.A(spi_sdo_int[2])); -ctech_delay_buf u_delay2_sdio2 (.X(spi_sdo2_d2),.A(spi_sdo2_d1)); -ctech_buf u_buf_sdio2 (.X(spi_sdo[2]),.A(spi_sdo2_d2)); - -wire spi_sdo3_d1,spi_sdo3_d2; -ctech_delay_buf u_delay1_sdio3 (.X(spi_sdo3_d1),.A(spi_sdo_int[3])); -ctech_delay_buf u_delay2_sdio3 (.X(spi_sdo3_d2),.A(spi_sdo3_d1)); -ctech_buf u_buf_sdio3 (.X(spi_sdo[3]),.A(spi_sdo3_d2)); - - -assign #1 spi_oen[0] = !spi_en_tx; // SPI_DIO0 -assign #1 spi_oen[1] = !spi_en_tx; // SPI_DIO1 -assign #1 spi_oen[2] = (spi_mode == 0) ? 1 'b0 : !spi_en_tx; // HOLD -assign #1 spi_oen[3] = (spi_mode == 0) ? 1 'b0 : !spi_en_tx; // - -// spi clock skew control -clk_skew_adjust u_skew_spi - ( -`ifdef USE_POWER_PINS - .vccd1 (vccd1 ),// User area 1 1.8V supply - .vssd1 (vssd1 ),// User area 1 digital ground -`endif - .clk_in (wbd_clk_int ), - .sel (cfg_cska_spi ), - .clk_out (wbd_clk_spi ) - ); - -// Clock Skey for SPI clock out -clk_skew_adjust u_skew_sp_co - ( -`ifdef USE_POWER_PINS - .vccd1 (vccd1 ),// User area 1 1.8V supply - .vssd1 (vssd1 ),// User area 1 digital ground -`endif - .clk_in (spi_clk_int ), - .sel (cfg_cska_sp_co ), - .clk_out (spi_clk ) - ); -//################################### -// Application Reset Synchronization -//################################### -reset_sync u_app_rst ( - .scan_mode (1'b0 ), - .dclk (mclk ), // Destination clock domain - .arst_n (rst_n ), // active low async reset - .srst_n (rst_ss_n ) - ); -qspim_if #( .WB_WIDTH(WB_WIDTH)) u_wb_if( - .mclk (mclk ), - .rst_n (rst_ss_n ), - - .wbd_stb_i (wbd_stb_i ), // strobe/request - .wbd_adr_i (wbd_adr_i ), // address - .wbd_we_i (wbd_we_i ), // write - .wbd_dat_i (wbd_dat_i ), // data output - .wbd_sel_i (wbd_sel_i ), // byte enable - .wbd_dat_o (wbd_dat_o ), // data input - .wbd_ack_o (wbd_ack_o ), // acknowlegement - .wbd_err_o (wbd_err_o ), // error - - // Configuration - .cfg_fsm_reset (cfg_m0_fsm_reset ), - .cfg_mem_seq (cfg_m0_spi_seq ), // SPI MEM SEQUENCE - .cfg_addr_cnt (cfg_m0_addr_cnt ), // SPI Addr Count - .cfg_dummy_cnt (cfg_m0_dummy_cnt ), // SPI Dummy Count - .cfg_data_cnt (cfg_m0_data_cnt ), // SPI Read Count - .cfg_cmd_reg (cfg_m0_cmd_reg ), // SPI MEM COMMAND - .cfg_mode_reg (cfg_m0_mode_reg ), // SPI MODE REG - - .spi_init_done (spi_init_done ), // SPI internal Init completed - - // Towards Reg I/F - .spim_reg_req (spim_reg_req ), // Reg Request - .spim_reg_addr (spim_reg_addr ), // Reg Address - .spim_reg_we (spim_reg_we ), // Reg Write/Read Command - .spim_reg_be (spim_reg_be ), // Reg Byte Enable - .spim_reg_wdata (spim_reg_wdata ), // Reg Write Data - .spim_reg_ack (spim_reg_ack ), // Read Ack - .spim_reg_rdata (spim_reg_rdata ), // Read Read Data - - // Towards Command FIFO - .cmd_fifo_empty (m0_cmd_fifo_empty ), // Command FIFO empty - .cmd_fifo_wr (m0_cmd_fifo_wr ), // Command FIFO Write - .cmd_fifo_wdata (m0_cmd_fifo_wdata ), // Command FIFO WData - - // Towards Response FIFO - .res_fifo_empty (m0_res_fifo_empty ), // Response FIFO Empty - .res_fifo_rd (m0_res_fifo_rd ), // Response FIFO Read - .res_fifo_rdata (m0_res_fifo_rdata ), // Response FIFO Data - - .state (m0_state ) - - ); - - -qspim_regs - #( - .WB_WIDTH(WB_WIDTH) - ) - u_spim_regs - ( - .mclk (mclk ), - .rst_n (rst_ss_n ), - .fast_sim_mode (1'b0 ), - - .spi_clk_div (spi_clk_div ), - .spi_init_done (spi_init_done ), - - .spi_debug (spi_debug ), - - .cfg_m0_fsm_reset (cfg_m0_fsm_reset ), - .cfg_m0_cs_reg (cfg_m0_cs_reg ), // Chip select - .cfg_m0_spi_mode (cfg_m0_spi_mode ), // Final SPI Mode - .cfg_m0_spi_switch (cfg_m0_spi_switch ), // SPI Mode Switching Place - .cfg_m0_spi_seq (cfg_m0_spi_seq ), // SPI SEQUENCE - .cfg_m0_addr_cnt (cfg_m0_addr_cnt ), // SPI Addr Count - .cfg_m0_dummy_cnt (cfg_m0_dummy_cnt ), // SPI Dummy Count - .cfg_m0_data_cnt (cfg_m0_data_cnt ), // SPI Read Count - .cfg_m0_cmd_reg (cfg_m0_cmd_reg ), // SPI MEM COMMAND - .cfg_m0_mode_reg (cfg_m0_mode_reg ), // SPI MODE REG - - .cfg_m1_cs_reg (cfg_m1_cs_reg ), // Chip select - .cfg_m1_spi_mode (cfg_m1_spi_mode ), // Final SPI Mode - .cfg_m1_spi_switch (cfg_m1_spi_switch ), // SPI Mode Switching Place - - .cfg_cs_early (cfg_cs_early ), - .cfg_cs_late (cfg_cs_late ), - - // Towards Reg I/F - .spim_reg_req (spim_reg_req ), // Reg Request - .spim_reg_addr (spim_reg_addr ), // Reg Address - .spim_reg_we (spim_reg_we ), // Reg Write/Read Command - .spim_reg_be (spim_reg_be ), // Reg Byte Enable - .spim_reg_wdata (spim_reg_wdata ), // Reg Write Data - .spim_reg_ack (spim_reg_ack ), // Read Ack - .spim_reg_rdata (spim_reg_rdata ), // Read Read Data - - // Towards Command FIFO - .cmd_fifo_full (m1_cmd_fifo_full ), // Command FIFO empty - .cmd_fifo_empty (m1_cmd_fifo_empty ), // Command FIFO empty - .cmd_fifo_wr (m1_cmd_fifo_wr ), // Command FIFO Write - .cmd_fifo_wdata (m1_cmd_fifo_wdata ), // Command FIFO WData - - // Towards Response FIFO - .res_fifo_full (m1_res_fifo_full ), // Response FIFO Empty - .res_fifo_empty (m1_res_fifo_empty ), // Response FIFO Empty - .res_fifo_rd (m1_res_fifo_rd ), // Response FIFO Read - .res_fifo_rdata (m1_res_fifo_rdata ), // Response FIFO Data - - .state (m1_state ) - - ); - - // Master 0 Command FIFO -qspim_fifo #(.W(34), .DP(2)) u_m0_cmd_fifo ( - .clk (mclk ), - .reset_n (rst_ss_n ), - .flush (1'b0 ), - .wr_en (m0_cmd_fifo_wr ), - .wr_data (m0_cmd_fifo_wdata ), - .full (m0_cmd_fifo_full ), - .afull ( ), - .rd_en (m0_cmd_fifo_rd ), - .empty (m0_cmd_fifo_empty ), - .aempty ( ), - .rd_data (m0_cmd_fifo_rdata ) - ); - - // Master 0 Response FIFO -qspim_fifo #(.W(32), .DP(8)) u_m0_res_fifo ( - .clk (mclk ), - .reset_n (rst_ss_n ), - .flush (m0_res_fifo_flush ), - .wr_en (m0_res_fifo_wr ), - .wr_data (m0_res_fifo_wdata ), - .full (m0_res_fifo_full ), - .afull ( ), - .rd_en (m0_res_fifo_rd ), - .empty (m0_res_fifo_empty ), - .aempty ( ), - .rd_data (m0_res_fifo_rdata ) - ); - - // Master 1 Command FIFO -qspim_fifo #(.W(34), .DP(4)) u_m1_cmd_fifo ( - .clk (mclk ), - .reset_n (rst_ss_n ), - .flush (1'b0 ), - .wr_en (m1_cmd_fifo_wr ), - .wr_data (m1_cmd_fifo_wdata ), - .full (m1_cmd_fifo_full ), - .afull ( ), - .rd_en (m1_cmd_fifo_rd ), - .empty (m1_cmd_fifo_empty ), - .aempty ( ), - .rd_data (m1_cmd_fifo_rdata ) - ); - // Master 1 Response FIFO -qspim_fifo #(.W(32), .DP(8)) u_m1_res_fifo ( - .clk (mclk ), - .reset_n (rst_ss_n ), - .flush (m1_res_fifo_flush ), - .wr_en (m1_res_fifo_wr ), - .wr_data (m1_res_fifo_wdata ), - .full (m1_res_fifo_full ), - .afull ( ), - .rd_en (m1_res_fifo_rd ), - .empty (m1_res_fifo_empty ), - .aempty ( ), - .rd_data (m1_res_fifo_rdata ) - ); - - -qspim_ctrl u_spictrl - ( - .clk (mclk ), - .rstn (rst_ss_n ), - - .spi_clk_div (spi_clk_div ), - .spi_status (spi_ctrl_status ), - - .cfg_m0_cs_reg (cfg_m0_cs_reg ), // Chip select - .cfg_m0_spi_mode (cfg_m0_spi_mode ), // Final SPI Mode - .cfg_m0_spi_switch (cfg_m0_spi_switch ), // SPI Mode Switching Place - - .cfg_m1_cs_reg (cfg_m1_cs_reg ), // Chip select - .cfg_m1_spi_mode (cfg_m1_spi_mode ), // Final SPI Mode - .cfg_m1_spi_switch (cfg_m1_spi_switch ), // SPI Mode Switching Place - - .cfg_cs_early (cfg_cs_early ), - .cfg_cs_late (cfg_cs_late ), - - .m0_cmd_fifo_empty (m0_cmd_fifo_empty ), - .m0_cmd_fifo_rd (m0_cmd_fifo_rd ), - .m0_cmd_fifo_rdata (m0_cmd_fifo_rdata ), - - .m0_res_fifo_flush (m0_res_fifo_flush ), - .m0_res_fifo_empty (m0_res_fifo_empty ), - .m0_res_fifo_full (m0_res_fifo_full ), - .m0_res_fifo_wr (m0_res_fifo_wr ), - .m0_res_fifo_wdata (m0_res_fifo_wdata ), - - .m1_cmd_fifo_empty (m1_cmd_fifo_empty ), - .m1_cmd_fifo_rd (m1_cmd_fifo_rd ), - .m1_cmd_fifo_rdata (m1_cmd_fifo_rdata ), - - .m1_res_fifo_flush (m1_res_fifo_flush ), - .m1_res_fifo_empty (m1_res_fifo_empty ), - .m1_res_fifo_full (m1_res_fifo_full ), - .m1_res_fifo_wr (m1_res_fifo_wr ), - .m1_res_fifo_wdata (m1_res_fifo_wdata ), - - .ctrl_state (ctrl_state ), - - .spi_clk (spi_clk_int ), - .spi_csn0 (spi_csn0 ), - .spi_csn1 (spi_csn1 ), - .spi_csn2 (spi_csn2 ), - .spi_csn3 (spi_csn3 ), - .spi_mode (spi_mode ), - .spi_sdo0 (spi_sdo_int[0] ), - .spi_sdo1 (spi_sdo_int[1] ), - .spi_sdo2 (spi_sdo_int[2] ), - .spi_sdo3 (spi_sdo_int[3] ), - .spi_sdi0 (spi_sdi[0] ), - .spi_sdi1 (spi_sdi[1] ), - .spi_sdi2 (spi_sdi[2] ), - .spi_sdi3 (spi_sdi[3] ), - .spi_en_tx_out (spi_en_tx ) - ); - -endmodule
diff --git a/verilog/rtl/qspim/src/qspim_tx.sv b/verilog/rtl/qspim/src/qspim_tx.sv deleted file mode 100644 index d80737c..0000000 --- a/verilog/rtl/qspim/src/qspim_tx.sv +++ /dev/null
@@ -1,249 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021 , Dinesh Annayya -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the 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. -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> -// -////////////////////////////////////////////////////////////////////// -//// //// -//// SPI TX Module //// -//// //// -//// This file is part of the YIFive cores project //// -//// https://github.com/dineshannayya/yifive_r0.git //// -//// http://www.opencores.org/cores/yifive/ //// -//// //// -//// Description //// -//// This is SPI Master Transmit Word control logic. //// -//// This logic transmit data upto 32 bit in bit or Quad spi //// -//// mode //// -//// //// -//// To Do: //// -//// nothing //// -//// //// -//// Author(s): //// -//// - Dinesh Annayya, dinesha@opencores.org //// -//// //// -//// Revision: //// -//// 0.1 - 16th Feb 2021, Dinesh A //// -//// Initial version //// -//// 0.2 - 24th Mar 2021, Dinesh A //// -//// 1. Comments are added //// -//// 2. RTL clean-up done and the output are registred//// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000 Authors and OPENCORES.ORG //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source 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 Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// - -module qspim_tx -( - // General Input - input logic clk, // SPI clock - input logic rstn, // Active low Reset - input logic flush, // init the state - input logic en, // Transmit Enable - input logic tx_edge, // Transmiting Edge - output logic tx_done, // Transmission completion - output logic sdo0, // SPI Dout0 - output logic sdo1, // SPI Dout1 - output logic sdo2, // SPI Dout2 - output logic sdo3, // SPI Dout3 - input logic [1:0] s_spi_mode, // SPI quad mode indication - input logic [15:0] counter_in, // Transmit counter - input logic counter_in_upd, - input logic [31:0] txdata, // 32 bit tranmsit data - input logic dummy_phase, // dummy data - input logic data_valid, // Input data valid - output logic data_ready, // Data in acepted, this for txfifo - output logic spi_dummy, // spi dummy phase - output logic clk_en_o // Enable Tx clock -); - -//------------------------------------------------------ -// Parameter Decleration -// ----------------------------------------------------- - parameter P_SINGLE = 2'b00; - parameter P_DOUBLE = 2'b01; - parameter P_QUAD = 2'b10; - parameter P_QDDR = 2'b11; - -//------------------------------------------------------ -// Variable Decleration -// ----------------------------------------------------- - logic [31:0] data_int ; // Data Input - logic [31:0] data_int_next ; // Next Data Input - logic [15:0] counter ; // Tx Counter - logic [15:0] counter_next ; // tx next counter - logic [15:0] counter_trgt ; // counter exit counter - logic tx32b_done ; // 32 bit Transmit done - logic [1:0] spi_mode ; - logic [1:0] spi_mode_next; - - logic data_ready_i; // Data in acepted, this for txfifo - logic next_data_ready_i;// Data in acepted, this for txfifo - enum logic [1:0] { IDLE, TRANSMIT,WAIT_FIFO_AVAIL } tx_CS, tx_NS; - - - // Indicate 32 bit data done, usefull for readining next 32b from txfifo - assign tx32b_done = (spi_mode == P_SINGLE && (counter[4:0] == 5'b11111)) || - (spi_mode == P_DOUBLE && (counter[3:0] == 4'b1111)) || - (spi_mode == P_QUAD && (counter[2:0] == 3'b111)) || - (spi_mode == P_QDDR && (counter[2:0] == 3'b111)); - - assign tx_done = (counter == (counter_trgt-1)) && (tx_CS == TRANSMIT); - - assign clk_en_o = (tx_NS == TRANSMIT); - - always_comb - begin - tx_NS = tx_CS; - data_int_next = data_int; - data_ready_i = 1'b0; - next_data_ready_i = 1'b0; - counter_next = counter; - spi_mode_next = spi_mode; - - case (tx_CS) - IDLE: begin - data_int_next = txdata; - counter_next = '0; - - if (en && data_valid && tx_edge) begin - spi_mode_next = s_spi_mode; - data_ready_i = 1'b1; - tx_NS = TRANSMIT; - end - end - - TRANSMIT: begin - if ((counter + 1) ==counter_trgt) begin - counter_next = 0; - // Check if there is next data - if (en && data_valid && tx_edge) begin - spi_mode_next = s_spi_mode; - data_int_next = txdata; - data_ready_i = 1'b1; - tx_NS = TRANSMIT; - end else begin - tx_NS = IDLE; - end - end else if (tx32b_done) begin - if (en && (spi_dummy || data_valid) && tx_edge) begin - spi_mode_next = s_spi_mode; - data_int_next = txdata; - next_data_ready_i = 1'b1; - counter_next = counter + 1; - tx_NS = TRANSMIT; - end else begin - tx_NS = WAIT_FIFO_AVAIL; - end - end else begin - counter_next = counter + 1; - data_int_next = (spi_mode == P_QDDR ) ? {data_int[27:0],4'b0000} : - (spi_mode == P_QUAD ) ? {data_int[27:0],4'b0000} : - (spi_mode == P_DOUBLE ) ? {data_int[29:0],2'b00} : {data_int[30:0],1'b0}; - end - end - WAIT_FIFO_AVAIL: begin - if (en && data_valid && tx_edge) begin - spi_mode_next = s_spi_mode; - data_int_next = txdata; - data_ready_i = 1'b1; - tx_NS = TRANSMIT; - end - end - endcase - end - - logic data_ready_f; - - always_ff @(posedge clk, negedge rstn) - begin - if (~rstn) - begin - counter <= 0; - data_int <= 'h0; - tx_CS <= IDLE; - sdo0 <= '0; - sdo1 <= '0; - sdo2 <= '1; - sdo3 <= '1; - counter_trgt <= '0; - data_ready <= '0; - data_ready_f <= 0; - spi_dummy <= 0; - spi_mode <= P_SINGLE; - end - else if(flush && tx_edge) begin - counter <= 0; - data_int <= 'h0; - tx_CS <= IDLE; - sdo0 <= '0; - sdo1 <= '0; - sdo2 <= '1; - sdo3 <= '1; - counter_trgt <= '0; - data_ready <= '0; - data_ready_f <= 0; - spi_dummy <= dummy_phase; - spi_mode <= P_SINGLE; - end else begin - data_ready_f <= data_ready_i | next_data_ready_i; - data_ready <= data_ready_f && !(data_ready_i | next_data_ready_i); // Generate Pulse at falling edge - if(tx_edge || (spi_mode_next == P_QDDR)) begin - tx_CS <= tx_NS; - counter <= counter_next; - data_int <= data_int_next; - end - // Counter Exit condition, quad mode div-4 , else actual counter - if (en && data_ready_i && tx_edge) begin - spi_mode <= s_spi_mode; - spi_dummy <= dummy_phase; - counter_trgt <= (s_spi_mode == P_QDDR ) ? {2'b00,counter_in[15:2]} : - (s_spi_mode == P_QUAD ) ? {2'b00,counter_in[15:2]} : - (s_spi_mode == P_DOUBLE ) ? {1'b0, counter_in[15:1]} : counter_in; - end else if (en == 0) begin - spi_dummy <= '0; - end - if((tx_edge || (spi_mode_next == P_QDDR)) && tx_NS == TRANSMIT) begin - sdo0 <= ((spi_mode_next == P_QUAD) || (spi_mode_next == P_QDDR))? data_int_next[28] : (spi_mode_next == P_DOUBLE) ? data_int_next[30] : data_int_next[31]; - sdo1 <= ((spi_mode_next == P_QUAD) || (spi_mode_next == P_QDDR))? data_int_next[29] : (spi_mode_next == P_DOUBLE) ? data_int_next[31] : 1'b0; - sdo2 <= ((spi_mode_next == P_QUAD) || (spi_mode_next == P_QDDR))? data_int_next[30] : 1'b1; // Protect - sdo3 <= ((spi_mode_next == P_QUAD) || (spi_mode_next == P_QDDR))? data_int_next[31] : 1'b1; // Hold need to '1' - end - end - end -endmodule
diff --git a/verilog/rtl/qspim/synth/Makefile b/verilog/rtl/qspim/synth/Makefile deleted file mode 100644 index dcf29dc..0000000 --- a/verilog/rtl/qspim/synth/Makefile +++ /dev/null
@@ -1,52 +0,0 @@ -# ////////////////////////////////////////////////////////////////////////////// -# // SPDX-FileCopyrightText: 2021, Dinesh Annayya -# // -# // Licensed under the Apache License, Version 2.0 (the "License"); -# // you may not use this file except in compliance with the License. -# // You may obtain a copy of the License at -# // -# // http://www.apache.org/licenses/LICENSE-2.0 -# // -# // Unless required by applicable law or agreed to in writing, software -# // distributed under the 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. -# // SPDX-License-Identifier: Apache-2.0 -# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org> -# // ////////////////////////////////////////////////////////////////////////// -#------------------------------------------------------------------------------ -# Makefile for Synthesis -#------------------------------------------------------------------------------ - -# Paths -export ROOT_DIR := $(shell pwd) -export REPORT_DIR := $(ROOT_DIR)/reports -export NETLIST_DIR := $(ROOT_DIR)/netlist -export TMP_DIR := $(ROOT_DIR)/tmp - - -# Targets -.PHONY: clean create synth - -default: clean create synth - -synth: clean create - yosys -g -c synth.tcl -l synth.log - -create: - mkdir -p ./tmp/synthesis; - mkdir -p ./reports; - mkdir -p ./netlist; - $(OPENLANE_ROOT)/scripts/libtrim.pl $(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib $(PDK_ROOT)/sky130A/libs.tech/openlane/sky130_fd_sc_hd/no_synth.cells > ./tmp/trimmed.lib - #create No PG Pin library for hand instantiated cells - sed '/pg_pin.*/a \ direction : "inout";' $(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib > ./tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib - sed -i 's/pg_pin/pin/' ./tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib - - - -clean: - $(RM) -R synth.log - $(RM) -R $(REPORT_DIR) - $(RM) -R $(NETLIST_DIR) - $(RM) -R $(TMP_DIR)
diff --git a/verilog/rtl/qspim/synth/synth.tcl b/verilog/rtl/qspim/synth/synth.tcl deleted file mode 100755 index 0285cc5..0000000 --- a/verilog/rtl/qspim/synth/synth.tcl +++ /dev/null
@@ -1,402 +0,0 @@ -# ////////////////////////////////////////////////////////////////////////////// -# // SPDX-FileCopyrightText: 2021, Dinesh Annayya -# // -# // Licensed under the Apache License, Version 2.0 (the "License"); -# // you may not use this file except in compliance with the License. -# // You may obtain a copy of the License at -# // -# // http://www.apache.org/licenses/LICENSE-2.0 -# // -# // Unless required by applicable law or agreed to in writing, software -# // distributed under the 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. -# // SPDX-License-Identifier: Apache-2.0 -# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org> -# // ////////////////////////////////////////////////////////////////////////// -# inputs expected as env vars -#set opt $::env(SYNTH_OPT) - -proc convert_pg_pins {lib_in lib_out} { - try_catch sed -E {s/^([[:space:]]+)pg_pin(.*)/\1pin\2\n\1 direction : "inout";/g} $lib_in > $lib_out -} - - - -########### config.tcl ################## -# User config -set ::env(DESIGN_NAME) qspim_top - -# Change if needed -set ::env(VERILOG_FILES) [glob \ - ../src/qspim_if.sv \ - ../src/qspim_clkgen.sv \ - ../src/qspim_ctrl.sv \ - ../src/qspim_fifo.sv \ - ../src/qspim_regs.sv \ - ../src/qspim_rx.sv \ - ../src/qspim_top.sv \ - ../src/qspim_tx.sv \ - ../lib/clk_skew_adjust.gv \ - ../lib/ctech_cells.sv \ - ../lib/reset_sync.sv \ - ] - - -set ::env(SYNTH_DEFINES) [list SYNTHESIS ] - - -set ::env(LIB_SYNTH) ./tmp/trimmed.lib -set ::env(LIB_SYNTH_COMPLETE_NO_PG) ./tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib - - - -# Fill this -set ::env(CLOCK_PERIOD) "10" -set ::env(CLOCK_PORT) "mclk" -set ::env(CLOCK_TREE_SYNTH) 0 - -set ::env(SYNTH_BUFFERING) 0 -set ::env(SYNTH_SIZING) 0 - -set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8" -set ::env(SYNTH_CAP_LOAD) "17.65" -set ::env(SYNTH_MAX_TRAN) "[expr {0.1*10.0}]" - -set ::env(SYNTH_MAX_FANOUT) 6 -set ::env(FP_CORE_UTIL) 50 -set ::env(PL_TARGET_DENSITY) [ expr ($::env(FP_CORE_UTIL)+5) / 100.0 ] -set ::env(CELL_PAD) 4 - -set ::env(SYNTH_NO_FLAT) "0" - -set ::env(SYNTH_READ_BLACKBOX_LIB) "1" - -set ::env(SYNTH_STRATEGY) "AREA 0" -set ::env(SYNTH_TIELO_PORT) "sky130_fd_sc_hd__conb_1 LO" -set ::env(SYNTH_TIEHI_PORT) "sky130_fd_sc_hd__conb_1 HI" -set ::env(SYNTH_MIN_BUF_PORT) "sky130_fd_sc_hd__buf_2 A X" - - -set ::env(CLOCK_NET) $::env(CLOCK_PORT) - - - -set ::env(yosys_tmp_file_tag) "./tmp/" -set ::env(TMP_DIR) "./tmp/" -set ::env(yosys_netlist_dir) "./netlist" -set ::env(yosys_report_file_tag) "./reports/yosys" -set ::env(yosys_result_file_tag) "./reports/yosys.synthesis" - -set ::env(SAVE_NETLIST) $::env(yosys_netlist_dir)/$::env(DESIGN_NAME).gv - - - -########### End of config.tcl -set buffering $::env(SYNTH_BUFFERING) -set sizing $::env(SYNTH_SIZING) - -yosys -import - -set vtop $::env(DESIGN_NAME) -#set sdc_file $::env(SDC_FILE) -set sclib $::env(LIB_SYNTH) - -if { [info exists ::env(SYNTH_DEFINES) ] } { - foreach define $::env(SYNTH_DEFINES) { - log "Defining $define" - verilog_defines -D$define - } -} - -set vIdirsArgs "" -if {[info exist ::env(VERILOG_INCLUDE_DIRS)]} { - foreach dir $::env(VERILOG_INCLUDE_DIRS) { - log "Adding include file -I$dir " - lappend vIdirsArgs "-I$dir" - } - set vIdirsArgs [join $vIdirsArgs] -} - -if { $::env(SYNTH_READ_BLACKBOX_LIB) } { - log "Reading $::env(LIB_SYNTH_COMPLETE_NO_PG) as a blackbox" - read_liberty -lib -ignore_miss_dir -setattr blackbox $::env(LIB_SYNTH_COMPLETE_NO_PG) -} - - -if { [info exists ::env(EXTRA_LIBS) ] } { - foreach lib $::env(EXTRA_LIBS) { - read_liberty {*}$vIdirsArgs -lib -ignore_miss_dir -setattr blackbox $lib - } -} - - - -# ns expected (in sdc as well) -set clock_period [expr {$::env(CLOCK_PERIOD)*1000}] - -set driver $::env(SYNTH_DRIVING_CELL) -set cload $::env(SYNTH_CAP_LOAD) -# input pin cap of IN_3VX8 -set max_FO $::env(SYNTH_MAX_FANOUT) -if {![info exist ::env(SYNTH_MAX_TRAN)]} { - set ::env(SYNTH_MAX_TRAN) [expr {0.1*$clock_period}] -} else { - set ::env(SYNTH_MAX_TRAN) [expr {$::env(SYNTH_MAX_TRAN) * 1000}] -} -set max_Tran $::env(SYNTH_MAX_TRAN) - - -# Mapping parameters -set A_factor 0.00 -set B_factor 0.88 -set F_factor 0.00 - -# Don't change these unless you know what you are doing -set stat_ext ".stat.rpt" -set chk_ext ".chk.rpt" -set gl_ext ".gl.v" -set constr_ext ".$clock_period.constr" -set timing_ext ".timing.txt" -set abc_ext ".abc" - - -# get old sdc, add library specific stuff for abc scripts -set sdc_file $::env(yosys_tmp_file_tag).sdc -set outfile [open ${sdc_file} w] -#puts $outfile $sdc_data -puts $outfile "set_driving_cell ${driver}" -puts $outfile "set_load ${cload}" -close $outfile - - -# ABC Scrips -set abc_rs_K "resub,-K," -set abc_rs "resub" -set abc_rsz "resub,-z" -set abc_rw_K "rewrite,-K," -set abc_rw "rewrite" -set abc_rwz "rewrite,-z" -set abc_rf "refactor" -set abc_rfz "refactor,-z" -set abc_b "balance" - -set abc_resyn2 "${abc_b}; ${abc_rw}; ${abc_rf}; ${abc_b}; ${abc_rw}; ${abc_rwz}; ${abc_b}; ${abc_rfz}; ${abc_rwz}; ${abc_b}" -set abc_share "strash; multi,-m; ${abc_resyn2}" -set abc_resyn2a "${abc_b};${abc_rw};${abc_b};${abc_rw};${abc_rwz};${abc_b};${abc_rwz};${abc_b}" -set abc_resyn3 "balance;resub;resub,-K,6;balance;resub,-z;resub,-z,-K,6;balance;resub,-z,-K,5;balance" -set abc_resyn2rs "${abc_b};${abc_rs_K},6;${abc_rw};${abc_rs_K},6,-N,2;${abc_rf};${abc_rs_K},8;${abc_rw};${abc_rs_K},10;${abc_rwz};${abc_rs_K},10,-N,2;${abc_b},${abc_rs_K},12;${abc_rfz};${abc_rs_K},12,-N,2;${abc_rwz};${abc_b}" - -set abc_choice "fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore" -set abc_choice2 "fraig_store; balance; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore" - -set abc_map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0" -set abc_map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0" -set abc_retime_area "retime,-D,{D},-M,5" -set abc_retime_dly "retime,-D,{D},-M,6" -set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000" - -set abc_area_recovery_1 "${abc_choice}; map;" -set abc_area_recovery_2 "${abc_choice2}; map;" - -set map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0" -set map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0" -set abc_retime_area "retime,-D,{D},-M,5" -set abc_retime_dly "retime,-D,{D},-M,6" -set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000" - -if {$buffering==1} { - set abc_fine_tune "buffer,-N,${max_FO},-S,${max_Tran};upsize,{D};dnsize,{D}" -} elseif {$sizing} { - set abc_fine_tune "upsize,{D};dnsize,{D}" -} else { - set abc_fine_tune "" -} - - -set delay_scripts [list \ - "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ - \ - "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice2};${abc_map_old_dly};${abc_area_recovery_2}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ - \ - "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice};${abc_map_old_dly};${abc_area_recovery_1}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ - \ - "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ - ] - -set area_scripts [list \ - "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ - \ - "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ - \ - "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_choice2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ - ] - -set all_scripts [list {*}$delay_scripts {*}$area_scripts] - -set strategy_parts [split $::env(SYNTH_STRATEGY)] - -proc synth_strategy_format_err { } { - upvar area_scripts area_scripts - upvar delay_scripts delay_scripts - log -stderr "\[ERROR] Misformatted SYNTH_STRATEGY (\"$::env(SYNTH_STRATEGY)\")." - log -stderr "\[ERROR] Correct format is \"DELAY|AREA 0-[expr [llength $delay_scripts]-1]|0-[expr [llength $area_scripts]-1]\"." - exit 1 -} - -if { [llength $strategy_parts] != 2 } { - synth_strategy_format_err -} - -set strategy_type [lindex $strategy_parts 0] -set strategy_type_idx [lindex $strategy_parts 1] - -if { $strategy_type != "AREA" && $strategy_type != "DELAY" } { - log -stderr "\[ERROR] AREA|DELAY tokens not found. ($strategy_type)" - synth_strategy_format_err -} - -if { $strategy_type == "DELAY" && $strategy_type_idx >= [llength $delay_scripts] } { - log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high." - synth_strategy_format_err -} - -if { $strategy_type == "AREA" && $strategy_type_idx >= [llength $area_scripts] } { - log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high." - synth_strategy_format_err -} - -if { $strategy_type == "DELAY" } { - set strategy $strategy_type_idx -} else { - set strategy [expr {[llength $delay_scripts]+$strategy_type_idx}] -} - - -for { set i 0 } { $i < [llength $::env(VERILOG_FILES)] } { incr i } { - read_verilog -sv {*}$vIdirsArgs [lindex $::env(VERILOG_FILES) $i] -} - -if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } { - foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) { - read_verilog -sv {*}$vIdirsArgs -lib $verilog_file - } -} -select -module $vtop -show -format dot -prefix $::env(TMP_DIR)/synthesis/hierarchy -select -clear - -hierarchy -check -top $vtop - -# Infer tri-state buffers. -set tbuf_map false -if { [info exists ::env(TRISTATE_BUFFER_MAP)] } { - if { [file exists $::env(TRISTATE_BUFFER_MAP)] } { - set tbuf_map true - tribuf - } else { - log "WARNING: TRISTATE_BUFFER_MAP is defined but could not be found: $::env(TRISTATE_BUFFER_MAP)" - } -} - -if { $::env(SYNTH_NO_FLAT) } { - synth -top $vtop -} else { - synth -top $vtop -flatten -} - -share -aggressive -opt -opt_clean -purge - -tee -o "$::env(yosys_report_file_tag)_pre.stat" stat - -# Map tri-state buffers. -if { $tbuf_map } { - log {mapping tbuf} - techmap -map $::env(TRISTATE_BUFFER_MAP) - simplemap -} - -# handle technology mapping of 4-MUX, and tell Yosys to infer 4-muxes -if { [info exists ::env(SYNTH_MUX4_MAP)] && [file exists $::env(SYNTH_MUX4_MAP)] } { - muxcover -mux4 - techmap -map $::env(SYNTH_MUX4_MAP) - simplemap -} - -# handle technology mapping of 2-MUX -if { [info exists ::env(SYNTH_MUX_MAP)] && [file exists $::env(SYNTH_MUX_MAP)] } { - techmap -map $::env(SYNTH_MUX_MAP) - simplemap -} - -# handle technology mapping of latches -if { [info exists ::env(SYNTH_LATCH_MAP)] && [file exists $::env(SYNTH_LATCH_MAP)] } { - techmap -map $::env(SYNTH_LATCH_MAP) - simplemap -} - -dfflibmap -liberty $sclib -tee -o "$::env(yosys_report_file_tag)_dff.stat" stat - -if { [info exists ::env(SYNTH_EXPLORE)] && $::env(SYNTH_EXPLORE) } { - design -save myDesign - - for { set index 0 } { $index < [llength $all_scripts] } { incr index } { - log "\[INFO\]: ABC: WireLoad : S_$index" - design -load myDesign - - abc -D $clock_period \ - -constr "$sdc_file" \ - -liberty $sclib \ - -script [lindex $all_scripts $index] - - setundef -zero - - hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT) - - # get rid of the assignments that make verilog2def fail - splitnets - opt_clean -purge - insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT) - - tee -o "$::env(yosys_report_file_tag)_$index$chk_ext" check - write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(yosys_result_file_tag)_$index.v" - design -reset - } -} else { - - log "\[INFO\]: ABC: WireLoad : S_$strategy" - - abc -D $clock_period \ - -constr "$sdc_file" \ - -liberty $sclib \ - -script [lindex $all_scripts $strategy] \ - -showtmp; - - setundef -zero - - hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT) - - # get rid of the assignments that make verilog2def fail - splitnets - opt_clean -purge - insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT) - - tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check - write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)" -} - -if { $::env(SYNTH_NO_FLAT) } { - design -reset - file copy -force $::env(SAVE_NETLIST) $::env(yosys_tmp_file_tag)_unflat.v - read_verilog -sv $::env(SAVE_NETLIST) - synth -top $vtop -flatten - splitnets - opt_clean -purge - insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT) - write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)" - tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check -}