Delete caravel/rtl directory
diff --git a/caravel/rtl/DFFRAM.v b/caravel/rtl/DFFRAM.v deleted file mode 100644 index 81d0970..0000000 --- a/caravel/rtl/DFFRAM.v +++ /dev/null
@@ -1,110 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -`ifndef USE_CUSTOM_DFFRAM - -module DFFRAM_1K ( -`ifdef USE_POWER_PINS - input VPWR, - input VGND, -`endif - input CLK, - input [3:0] WE, - input EN, - input [31:0] Di, - output reg [31:0] Do, - input [7:0] A -); - - -reg [31:0] mem [0:`MEM_WORDS-1]; - -always @(posedge CLK) begin - if (EN == 1'b1) begin - Do <= mem[A]; - if (WE[0]) mem[A][ 7: 0] <= Di[ 7: 0]; - if (WE[1]) mem[A][15: 8] <= Di[15: 8]; - if (WE[2]) mem[A][23:16] <= Di[23:16]; - if (WE[3]) mem[A][31:24] <= Di[31:24]; - end -end -endmodule - -`else - -module DFFRAM #(parameter USE_LATCH=`DFFRAM_USE_LATCH, - WSIZE=`DFFRAM_WSIZE ) -( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire CLK, // FO: 2 - input wire [WSIZE-1:0] WE, // FO: 2 - input EN, // FO: 2 - input wire [7:0] A, // FO: 5 - input wire [(WSIZE*8-1):0] Di, // FO: 2 - output wire [(WSIZE*8-1):0] Do - -); - - wire [1:0] SEL; - wire [(WSIZE*8-1):0] Do_pre[1:0]; - - // 1x2 DEC - DEC1x2 DEC ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .EN(EN), - .A(A[7]), - .SEL(SEL) - ); - - // sky130_fd_sc_hd__inv_2 DEC ( - // `ifdef USE_POWER_PINS - // .VPWR(VPWR), - // .VGND(VGND), - // .VPB(VPWR), - // .VNB(VGND), - // `endif - // .Y(SEL[0]), .A(A[7])); - // assign SEL[1] = A[7]; - - generate - genvar i; - for (i=0; i< 2; i=i+1) begin : BLOCK - RAM128 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM128 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .CLK(CLK), .EN(SEL[i]), .WE(WE), .Di(Di), .Do(Do_pre[i]), .A(A[6:0]) ); - end - endgenerate - - // Output MUX - MUX2x1 #(.WIDTH(WSIZE*8)) DoMUX ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .A0(Do_pre[0]), .A1(Do_pre[1]), .S(A[7]), .X(Do) ); - -endmodule - -`endif \ No newline at end of file
diff --git a/caravel/rtl/DFFRAMBB.v b/caravel/rtl/DFFRAMBB.v deleted file mode 100644 index 15fa627..0000000 --- a/caravel/rtl/DFFRAMBB.v +++ /dev/null
@@ -1,772 +0,0 @@ -/* - Copyright ©2020-2021 The American University in Cairo and the Cloud V Project. - - This file is part of the DFFRAM Memory Compiler. - See https://github.com/Cloud-V/DFFRAM for further info. - - 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. -*/ - -// Add 1x2 binary decoder -`default_nettype none - -module DEC1x2 ( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire EN, - input wire A, - output wire [1:0] SEL -); - - sky130_fd_sc_hd__and2b_2 AND0 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - - .X(SEL[0]), - .A_N(A), - .B(EN) - ); - - sky130_fd_sc_hd__and2_2 AND1 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - - .X(SEL[1]), - .A(A) , - .B(EN) - ); - -endmodule - -module DEC2x4 ( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input EN, - input [1:0] A, - output [3:0] SEL -); - sky130_fd_sc_hd__nor3b_4 AND0 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .Y(SEL[0]), .A(A[0]), .B(A[1]), .C_N(EN) ); - sky130_fd_sc_hd__and3b_4 AND1 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[1]), .A_N(A[1]), .B(A[0]), .C(EN) ); - sky130_fd_sc_hd__and3b_4 AND2 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[2]), .A_N(A[0]), .B(A[1]), .C(EN) ); - sky130_fd_sc_hd__and3_4 AND3 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[3]), .A(A[1]), .B(A[0]), .C(EN) ); - -endmodule - -module DEC3x8 ( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input EN, - input [2:0] A, - output [7:0] SEL -); - - wire [2:0] A_buf; - wire EN_buf; - - sky130_fd_sc_hd__clkbuf_2 ABUF[2:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(A_buf), .A(A)); - sky130_fd_sc_hd__clkbuf_2 ENBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(EN_buf), .A(EN)); - - sky130_fd_sc_hd__nor4b_2 AND0 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .Y(SEL[0]) , .A(A_buf[0]), .B(A_buf[1]) , .C(A_buf[2]), .D_N(EN_buf) ); // 000 - sky130_fd_sc_hd__and4bb_2 AND1 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[1]) , .A_N(A_buf[2]), .B_N(A_buf[1]), .C(A_buf[0]) , .D(EN_buf) ); // 001 - sky130_fd_sc_hd__and4bb_2 AND2 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[2]) , .A_N(A_buf[2]), .B_N(A_buf[0]), .C(A_buf[1]) , .D(EN_buf) ); // 010 - sky130_fd_sc_hd__and4b_2 AND3 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[3]) , .A_N(A_buf[2]), .B(A_buf[1]), .C(A_buf[0]) , .D(EN_buf) ); // 011 - sky130_fd_sc_hd__and4bb_2 AND4 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[4]) , .A_N(A_buf[0]), .B_N(A_buf[1]), .C(A_buf[2]) , .D(EN_buf) ); // 100 - sky130_fd_sc_hd__and4b_2 AND5 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[5]) , .A_N(A_buf[1]), .B(A_buf[0]), .C(A_buf[2]) , .D(EN_buf) ); // 101 - sky130_fd_sc_hd__and4b_2 AND6 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[6]) , .A_N(A_buf[0]), .B(A_buf[1]), .C(A_buf[2]) , .D(EN_buf) ); // 110 - sky130_fd_sc_hd__and4_2 AND7 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL[7]) , .A(A_buf[0]), .B(A_buf[1]), .C(A_buf[2]) , .D(EN_buf) ); // 111 -endmodule - -module MUX4x1 #(parameter WIDTH=32) -( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire [WIDTH-1:0] A0, A1, A2, A3, - input wire [1:0] S, - output wire [WIDTH-1:0] X -); - localparam SIZE = WIDTH/8; - wire [SIZE-1:0] SEL0, SEL1; - sky130_fd_sc_hd__clkbuf_2 SEL0BUF[SIZE-1:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL0), .A(S[0])); - - sky130_fd_sc_hd__clkbuf_2 SEL1BUF[SIZE-1:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL1), .A(S[1])); - - generate - genvar i; - for(i=0; i<SIZE; i=i+1) begin : M - sky130_fd_sc_hd__mux4_1 MUX[7:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .A0(A0[(i+1)*8-1:i*8]), - .A1(A1[(i+1)*8-1:i*8]), - .A2(A2[(i+1)*8-1:i*8]), - .A3(A3[(i+1)*8-1:i*8]), - .S0(SEL0[i]), - .S1(SEL1[i]), - .X(X[(i+1)*8-1:i*8]) ); - end - endgenerate -endmodule - -module MUX2x1 #(parameter WIDTH=32) -( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire [WIDTH-1:0] A0, A1, A2, A3, - input wire S, - output wire [WIDTH-1:0] X -); - localparam SIZE = WIDTH/8; - wire [SIZE-1:0] SEL; - sky130_fd_sc_hd__clkbuf_2 SELBUF[SIZE-1:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL), .A(S)); - generate - genvar i; - for(i=0; i<SIZE; i=i+1) begin : M - sky130_fd_sc_hd__mux2_1 MUX[7:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .A0(A0[(i+1)*8-1:i*8]), .A1(A1[(i+1)*8-1:i*8]), .S(SEL[i]), .X(X[(i+1)*8-1:i*8]) ); - end - endgenerate -endmodule - -module BYTE #( parameter USE_LATCH=`DFFRAM_USE_LATCH)( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire CLK, // FO: 1 - input wire WE, // FO: 1 - input wire SEL, // FO: 2 - input wire [7:0] Di, // FO: 1 - output wire [7:0] Do -); - - wire [7:0] q_wire; - wire we_wire; - wire SEL_B; - wire GCLK; - wire CLK_B; - - generate - genvar i; - - if(USE_LATCH == 1) begin - sky130_fd_sc_hd__inv_1 CLKINV( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .Y(CLK_B), .A(CLK)); - sky130_fd_sc_hd__dlclkp_1 CG( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .CLK(CLK_B), .GCLK(GCLK), .GATE(we_wire) ); - end else - sky130_fd_sc_hd__dlclkp_1 CG( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .CLK(CLK), .GCLK(GCLK), .GATE(we_wire) ); - - sky130_fd_sc_hd__inv_1 SELINV( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .Y(SEL_B), .A(SEL)); - sky130_fd_sc_hd__and2_1 CGAND( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .A(SEL), .B(WE), .X(we_wire) ); - - for(i=0; i<8; i=i+1) begin : BIT - if(USE_LATCH == 0) - sky130_fd_sc_hd__dfxtp_1 FF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .D(Di[i]), .Q(q_wire[i]), .CLK(GCLK) ); - else - sky130_fd_sc_hd__dlxtp_1 LATCH ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .Q(q_wire[i]), .D(Di[i]), .GATE(GCLK) ); - sky130_fd_sc_hd__ebufn_2 OBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .A(q_wire[i]), .Z(Do[i]), .TE_B(SEL_B) ); - end - endgenerate - -endmodule - - -module WORD #( parameter USE_LATCH=`DFFRAM_USE_LATCH, - WSIZE=`DFFRAM_WSIZE ) ( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire CLK, // FO: 1 - input wire [WSIZE-1:0] WE, // FO: 1 - input wire SEL, // FO: 1 - input wire [(WSIZE*8-1):0] Di, // FO: 1 - output wire [(WSIZE*8-1):0] Do -); - - wire SEL_buf; - wire CLK_buf; - sky130_fd_sc_hd__clkbuf_2 SELBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(SEL_buf), .A(SEL)); - sky130_fd_sc_hd__clkbuf_1 CLKBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(CLK_buf), .A(CLK)); - generate - genvar i; - for(i=0; i<WSIZE; i=i+1) begin : BYTE - BYTE #(.USE_LATCH(USE_LATCH)) B ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .CLK(CLK_buf), .WE(WE[i]), .SEL(SEL_buf), .Di(Di[(i+1)*8-1:i*8]), .Do(Do[(i+1)*8-1:i*8]) ); - end - endgenerate - -endmodule - - -module RAM8 #( parameter USE_LATCH=`DFFRAM_USE_LATCH, - WSIZE=`DFFRAM_WSIZE ) ( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire CLK, // FO: 1 - input wire [WSIZE-1:0] WE, // FO: 1 - input EN, // EN: 1 - input wire [2:0] A, // A: 1 - input wire [(WSIZE*8-1):0] Di, // FO: 1 - output wire [(WSIZE*8-1):0] Do -); - - wire [7:0] SEL; - wire [WSIZE-1:0] WE_buf; - wire CLK_buf; - - DEC3x8 DEC ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .EN(EN), .A(A), .SEL(SEL)); - sky130_fd_sc_hd__clkbuf_2 WEBUF[WSIZE-1:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(WE_buf), .A(WE)); - sky130_fd_sc_hd__clkbuf_2 CLKBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(CLK_buf), .A(CLK)); - - generate - genvar i; - for (i=0; i< 8; i=i+1) begin : WORD - WORD #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) W ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .CLK(CLK_buf), .WE(WE_buf), .SEL(SEL[i]), .Di(Di), .Do(Do) ); - end - endgenerate - -endmodule - - -// 4 x RAM8 slices (128 bytes) with registered outout -module RAM32 #( parameter USE_LATCH=`DFFRAM_USE_LATCH, - WSIZE=`DFFRAM_WSIZE ) -( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire CLK, // FO: 1 - input wire [WSIZE-1:0] WE, // FO: 1 - input EN, // FO: 1 - input wire [4:0] A, // FO: 1 - input wire [(WSIZE*8-1):0] Di, // FO: 1 - output wire [(WSIZE*8-1):0] Do - -); - wire [3:0] SEL; - wire [4:0] A_buf; - wire CLK_buf; - wire [WSIZE-1:0] WE_buf; - wire EN_buf; - - wire [(WSIZE*8-1):0] Do_pre; - wire [(WSIZE*8-1):0] Di_buf; - - // Buffers - // Di Buffers - sky130_fd_sc_hd__clkbuf_16 DIBUF[(WSIZE*8-1):0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(Di_buf), .A(Di)); - // Control signals buffers - sky130_fd_sc_hd__clkbuf_2 CLKBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(CLK_buf), .A(CLK)); - sky130_fd_sc_hd__clkbuf_2 WEBUF[(WSIZE-1):0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(WE_buf), .A(WE)); - sky130_fd_sc_hd__clkbuf_2 ABUF[4:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(A_buf), .A(A[4:0])); - sky130_fd_sc_hd__clkbuf_2 ENBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(EN_buf), .A(EN)); - - DEC2x4 DEC ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .EN(EN_buf), .A(A_buf[4:3]), .SEL(SEL)); - - generate - genvar i; - for (i=0; i< 4; i=i+1) begin : SLICE - RAM8 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM8 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .CLK(CLK_buf), .WE(WE_buf),.EN(SEL[i]), .Di(Di_buf), .Do(Do_pre), .A(A_buf[2:0]) ); - end - endgenerate - - // Ensure that the Do_pre lines are not floating when EN = 0 - wire [WSIZE-1:0] lo; - wire [WSIZE-1:0] float_buf_en; - sky130_fd_sc_hd__clkbuf_2 FBUFENBUF[WSIZE-1:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(float_buf_en), .A(EN) ); - sky130_fd_sc_hd__conb_1 TIE[WSIZE-1:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .LO(lo), .HI()); - - // Following split by group because each is done by one TIE CELL and ONE CLKINV_4 - // Provides default values for floating lines (lo) - generate - for (i=0; i< WSIZE; i=i+1) begin : BYTE - sky130_fd_sc_hd__ebufn_2 FLOATBUF[(8*(i+1))-1:8*i] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .A( lo[i] ), .Z(Do_pre[(8*(i+1))-1:8*i]), .TE_B(float_buf_en[i]) ); - end - endgenerate - - sky130_fd_sc_hd__dfxtp_1 Do_FF[WSIZE*8-1:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .D(Do_pre), .Q(Do), .CLK(CLK) ); - -endmodule - - -/* - 4 x RAM32 Blocks -*/ - -module RAM128 #(parameter USE_LATCH=`DFFRAM_USE_LATCH, - WSIZE=`DFFRAM_WSIZE ) -( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire CLK, // FO: 1 - input wire [WSIZE-1:0] WE, // FO: 1 - input EN, // FO: 1 - input wire [6:0] A, // FO: 1 - input wire [(WSIZE*8-1):0] Di, // FO: 1 - output wire [(WSIZE*8-1):0] Do - -); - - wire CLK_buf; - wire [WSIZE-1:0] WE_buf; - wire EN_buf; - wire [6:0] A_buf; - wire [(WSIZE*8-1):0] Di_buf; - wire [3:0] SEL; - - wire [(WSIZE*8-1):0] Do_pre[3:0]; - - // Buffers - sky130_fd_sc_hd__clkbuf_16 DIBUF[(WSIZE*8-1):0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(Di_buf), .A(Di)); - sky130_fd_sc_hd__clkbuf_4 CLKBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(CLK_buf), .A(CLK)); - sky130_fd_sc_hd__clkbuf_2 WEBUF[WSIZE-1:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(WE_buf), .A(WE)); - sky130_fd_sc_hd__clkbuf_2 ENBUF ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(EN_buf), .A(EN)); - sky130_fd_sc_hd__clkbuf_2 ABUF[6:0] ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .X(A_buf), .A(A)); - - DEC2x4 DEC ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .EN(EN_buf), .A(A_buf[6:5]), .SEL(SEL)); - - generate - genvar i; - for (i=0; i< 4; i=i+1) begin : BLOCK - RAM32 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM32 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .CLK(CLK_buf), .EN(SEL[i]), .WE(WE_buf), .Di(Di_buf), .Do(Do_pre[i]), .A(A_buf[4:0]) ); - end - endgenerate - - // Output MUX - MUX4x1 #(.WIDTH(WSIZE*8)) DoMUX ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .A0(Do_pre[0]), .A1(Do_pre[1]), .A2(Do_pre[2]), .A3(Do_pre[3]), .S(A_buf[6:5]), .X(Do) ); - -endmodule - -module RAM256 #(parameter USE_LATCH=`DFFRAM_USE_LATCH, - WSIZE=`DFFRAM_WSIZE ) -( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - input wire CLK, // FO: 2 - input wire [WSIZE-1:0] WE, // FO: 2 - input EN, // FO: 2 - input wire [7:0] A, // FO: 5 - input wire [(WSIZE*8-1):0] Di, // FO: 2 - output wire [(WSIZE*8-1):0] Do - -); - - wire [1:0] SEL; - wire [(WSIZE*8-1):0] Do_pre[1:0]; - - // 1x2 DEC - sky130_fd_sc_hd__inv_2 DEC ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .Y(SEL[0]), .A(A[7])); - assign SEL[1] = A[7]; - - generate - genvar i; - for (i=0; i< 2; i=i+1) begin : BLOCK - RAM128 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM128 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .CLK(CLK), .EN(SEL[i]), .WE(WE), .Di(Di), .Do(Do_pre[i]), .A(A[6:0]) ); - end - endgenerate - - // Output MUX - MUX2x1 #(.WIDTH(WSIZE*8)) DoMUX ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .A0(Do_pre[0]), .A1(Do_pre[1]), .S(A[7]), .X(Do) ); - -endmodule
diff --git a/caravel/rtl/README b/caravel/rtl/README deleted file mode 100644 index 8bcafd1..0000000 --- a/caravel/rtl/README +++ /dev/null
@@ -1,223 +0,0 @@ -<!--- -# SPDX-FileCopyrightText: 2020 Efabless Corporation -# -# 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 ---> - -A quick documentation of the Caravel memory map and operation ---------------------------------------------------------------- - -Caravel pinout: ---------------- - - vddio 3.3V supply for all I/O and ESD - vssio Ground for all I/O and ESD - vdda 3.3V supply for management area - vssa Ground for management area - vccd 1.8V supply for management area - vssd Digital ground for management area - - vdda1 3.3V supply for user area 1 - vdda2 3.3V supply for user area 2 - vssa1 Ground for user area 1 - vssa2 Ground for user area 2 - vccd1 1.8 supply for user area 1 - vccd2 1.8 supply for user area 2 - vssd1 Digital ground for user area 1 - vssd2 Digital ground for user area 2 - - clock Master clock input - gpio 1 bit, mainly used for external LDO control of user power supply - mprj_io 32 bits general purpose programmable digital or analog I/O - resetb Master reset (sense inverted) input - flash_csb SPI flash controller chip select (sense inverted) - flash_clk SPI flash controller clock - flash_io0 SPI flash controller data out - flash_io1 SPI flash controller data in - -Special-use pins for the management SoC: ----------------------------------------- - - On power-up, the "mprj_io" GPIO are under complete control of the managment - SoC. The first 8 user GPIO are special-purpose pads with dedicated functions - for the management SoC: - - mprj_io[0] JTAG I/O - mprj_io[1] SDO, housekeeping SPI - mprj_io[2] SDI, housekeeping SPI - mprj_io[3] CSB, housekeeping SPI - mprj_io[4] SCK, housekeeping SPI - mprj_io[5] Rx, UART - mprj_io[6] Tx, UART - mprj_io[7] IRQ - - The next 4 user GPIO are designed to be used with an SPI flash controller in - the user space. They allow the four pins to be overridden by the housekeeping - SPI to access the SPI flash in pass-through mode. - - mprj_io[8] user flash CSB - mprj_io[9] user flash SCK - mprj_io[10] user flash IO0 - mprj_io[11] user flash IO1 - - The last 2 GPIO pins can be used by the management SoC to drive the SPI flash - io2 and io3 pins for quad and DDR access, although they are set as inputs by - default and whenever the SPI flash is not in quad mode: - - mprj_io[36] SPI flash io2 - mprj_io[37] SPI flash io3 - - The user may additionally use any available GPIO for the SPI flash IO2 and IO3 - lines; the pass-through mode only uses the basic 4-pin SPI mode. - - All of the special-use pins are configured through a memory-mapped region. But - to avoid a large number of wires in the user space to reach all of the GPIO - pad controls, each user GPIO pad has a corresponding local control block. The - control block holds the configuration data for the corresponding pad. This - configuration data is a mirror of the data in the memory-mapped region, and is - loaded by a "transfer" bit in another memory-mapped register. In addition to - all of the static control bits for the GPIO, each block contains a single bit - that specifies whether that pad is under the control of the user or the management - area. All pins are configured from the management area. However, the configuration - of static control bits leaves three dynamic signals: input, output, and output - enable. One set of these three signals is available to the user when the pad is - under user control. The other set of these three signals is available to the - management SoC. Again, to reduce wiring, only the two pads for JTAG and the - housekeeping SDO have all three pins under control of the SoC; the remaining - pads have a single wire to the management SoC which is either an input wire - or an output wire, depending on how the control signals for the pad are set. - - This setup gives a simplified view of the pad to the user: For digital - applications, the user can treat the pad as a simple bidirectional digital - pad with an output enable to switch between output and input functions. - The user can set the output enable line high or low for a static input or - output function. The user will also have access to the ESD-protected - pad connections for analog signals, and can connect to the VDDA domain - input digital signal if needed. - -Memory map: ------------ - - The Caravel memory map is as follows: - - SRAM: 0000 0000 - - Flash: Config: 1000 0000 - - UART: Clock divider: 2000 0000 - Data: 2000 0004 - Enable 2000 0008 - - GPIO: Data: 2100 0000 - Output enable: 2100 0004 - Pullup 2100 0008 - Pulldown 2100 000c - - Counter 1: Config: 2200 0000 - Value: 2200 0004 - Data: 2200 0008 - - Counter 2: Config: 2300 0000 - Value: 2300 0004 - Data: 2300 0008 - - SPI master: Config: 2400 0000 - Data: 2400 0004 - - Logic analyzer: Data 0: 2500 0000 - Data 1: 2500 0004 - Data 2: 2500 0008 - Data 3: 2500 000c - Enable 0: 2500 0010 - Enable 1: 2500 0014 - Enable 2: 2500 0018 - Enable 3: 2500 001c - - Project ctrl: Data (L): 2600 0000 - Data (H): 2600 0004 - Transfer: 2600 0008 - I/O Config: 2600 000c - to 2600 009c - Power Config: 2600 00a0 - to 2600 0130 - - Flash ctrl: Config: 2D00 0000 - - System: PLL out: 2F00 0000 - Trap out: 2F00 0004 - IRQ7 source: 2F00 0008 - - User area base: 3000 0000 - - Crossbar: QSPI control 8000 0000 - Storage area 9000 0000 - Any slave 1 a000 0000 - Any slave 2 b000 0000 - -Project I/O Control: ---------------------- - - Configuration bits per I/O (13 bits for each GPIO pad): - Global Default - Bits 12-10: digital mode (3 bits) 001 - Bit 9: voltage trip point select 0 - Bit 8: slow slew select 0 - Bit 7: analog bus polarity 0 - Bit 6: analog bus select 0 - Bit 5: analog bus enable 0 - Bit 4: IB mode select 0 - Bit 3: input disable 0 - Bit 2: holdover value 0 - Bit 1: output disable 1 - Bit 0: management control enable 1 - -Default I/O modes: ------------------- - mprj_io[0] JTAG I/O 110 0 0 0 0 0 0 0 0 0 1 - mprj_io[1] SDO, housekeeping SPI 110 0 0 0 0 0 0 0 0 0 1 - all others: 001 0 0 0 0 0 0 0 0 1 1 - - - Standard GPIO output configuration: - mprj_io[6] Tx, UART 110 0 0 0 0 0 0 1 0 0 1 - - Standard GPIO input configuration: - mprj_io[*] 001 0 0 0 0 0 0 0 0 1 1 - - Standard GPIO input configuration with pullup: - mprj_io[*] 010 0 0 0 0 0 0 0 0 1 1 - - Standard GPIO input configuration with pulldown: - mprj_io[*] 011 0 0 0 0 0 0 0 0 1 1 - - Specifically: - JTAG and SDO are set to output. The output enable configure bit - is a don't-care, since the output enable line is directly controlled - by the module (JTAG or housekeeping SPI, respectively). - - All other I/O are set as input mode only, with output disabled. - - Tx is set to input like the others; before enabling the UART - from a program in flash, the I/O must be set to an output configuration. - - Note that the standard input configurations with pull-up and pull-down - require that "out" be set 1 or 0, respectively; since the I/O are - designed with minimal wiring, there is only one wire for input and - output, so the wire is used for input in these cases, and special - signal handling is done locally to set the value of "out" equal to - ~dm[0]. This is a (minor) restriction on the available I/O modes. - - Other possible modes are open-drain (for I2C), weak drive strength - output (5k up + down), and analog mode (digital disabled)
diff --git a/caravel/rtl/__uprj_analog_netlists.v b/caravel/rtl/__uprj_analog_netlists.v deleted file mode 100644 index 918b3c4..0000000 --- a/caravel/rtl/__uprj_analog_netlists.v +++ /dev/null
@@ -1,35 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 -/*--------------------------------------------------------------*/ -/* caravel, a project harness for the Google/SkyWater sky130 */ -/* fabrication process and open source PDK */ -/* */ -/* Copyright 2020 efabless, Inc. */ -/* Written by Tim Edwards, December 2019 */ -/* and Mohamed Shalan, August 2020 */ -/* This file is open source hardware released under the */ -/* Apache 2.0 license. See file LICENSE. */ -/* */ -/*--------------------------------------------------------------*/ - -`define USE_POWER_PINS - -`include "defines.v" - -`ifdef GL - `include "gl/__user_analog_project_wrapper.v" -`else - `include "__user_analog_project_wrapper.v" -`endif
diff --git a/caravel/rtl/__uprj_netlists.v b/caravel/rtl/__uprj_netlists.v deleted file mode 100644 index 673a32a..0000000 --- a/caravel/rtl/__uprj_netlists.v +++ /dev/null
@@ -1,35 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 -/*--------------------------------------------------------------*/ -/* caravel, a project harness for the Google/SkyWater sky130 */ -/* fabrication process and open source PDK */ -/* */ -/* Copyright 2020 efabless, Inc. */ -/* Written by Tim Edwards, December 2019 */ -/* and Mohamed Shalan, August 2020 */ -/* This file is open source hardware released under the */ -/* Apache 2.0 license. See file LICENSE. */ -/* */ -/*--------------------------------------------------------------*/ - -`define USE_POWER_PINS - -`include "defines.v" - -`ifdef GL - `include "gl/__user_project_wrapper.v" -`else - `include "__user_project_wrapper.v" -`endif \ No newline at end of file
diff --git a/caravel/rtl/__user_analog_project_wrapper.v b/caravel/rtl/__user_analog_project_wrapper.v deleted file mode 100644 index 6360f0b..0000000 --- a/caravel/rtl/__user_analog_project_wrapper.v +++ /dev/null
@@ -1,124 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -/* - *------------------------------------------------------------- - * - * user_analog_project_wrapper - * - * This wrapper enumerates all of the pins available to the - * user for the user analog project. - * - *------------------------------------------------------------- - */ - -module user_analog_project_wrapper ( -`ifdef USE_POWER_PINS - inout vdda1, // User area 1 3.3V supply - inout vdda2, // User area 2 3.3V supply - inout vssa1, // User area 1 analog ground - inout vssa2, // User area 2 analog ground - inout vccd1, // User area 1 1.8V supply - inout vccd2, // User area 2 1.8v supply - inout vssd1, // User area 1 digital ground - inout vssd2, // User area 2 digital ground -`endif - - // Wishbone Slave ports (WB MI A) - input wb_clk_i, - input wb_rst_i, - input wbs_stb_i, - input wbs_cyc_i, - input wbs_we_i, - input [3:0] wbs_sel_i, - input [31:0] wbs_dat_i, - input [31:0] wbs_adr_i, - output wbs_ack_o, - output [31:0] wbs_dat_o, - - // Logic Analyzer Signals - input [127:0] la_data_in, - output [127:0] la_data_out, - input [127:0] la_oenb, - - /* GPIOs. There are 27 GPIOs, on either side of the analog. - * These have the following mapping to the GPIO padframe pins - * and memory-mapped registers, since the numbering remains the - * same as caravel but skips over the analog I/O: - * - * io_in/out/oeb/in_3v3 [26:14] <---> mprj_io[37:25] - * io_in/out/oeb/in_3v3 [13:0] <---> mprj_io[13:0] - * - * When the GPIOs are configured by the Management SoC for - * user use, they have three basic bidirectional controls: - * in, out, and oeb (output enable, sense inverted). For - * analog projects, a 3.3V copy of the signal input is - * available. out and oeb must be 1.8V signals. - */ - - input [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] io_in, - input [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] io_in_3v3, - output [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] io_out, - output [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] io_oeb, - - /* Analog (direct connection to GPIO pad---not for high voltage or - * high frequency use). The management SoC must turn off both - * input and output buffers on these GPIOs to allow analog access. - * These signals may drive a voltage up to the value of VDDIO - * (3.3V typical, 5.5V maximum). - * - * Note that analog I/O is not available on the 7 lowest-numbered - * GPIO pads, and so the analog_io indexing is offset from the - * GPIO indexing by 7, as follows: - * - * gpio_analog/noesd [17:7] <---> mprj_io[35:25] - * gpio_analog/noesd [6:0] <---> mprj_io[13:7] - * - */ - - inout [`MPRJ_IO_PADS-`ANALOG_PADS-10:0] gpio_analog, - inout [`MPRJ_IO_PADS-`ANALOG_PADS-10:0] gpio_noesd, - - /* Analog signals, direct through to pad. These have no ESD at all, - * so ESD protection is the responsibility of the designer. - * - * user_analog[10:0] <---> mprj_io[24:14] - * - */ - inout [`ANALOG_PADS-1:0] io_analog, - - /* Additional power supply ESD clamps, one per analog pad. The - * high side should be connected to a 3.3-5.5V power supply. - * The low side should be connected to ground. - * - * clamp_high[2:0] <---> mprj_io[20:18] - * clamp_low[2:0] <---> mprj_io[20:18] - * - */ - inout [2:0] io_clamp_high, - inout [2:0] io_clamp_low, - - // Independent clock (on independent integer divider) - input user_clock2, - - // User maskable interrupt signals - output [2:0] user_irq -); - -// Dummy assignment so that we can take it through the openlane flow -assign io_out = io_in; - -endmodule // user_analog_project_wrapper
diff --git a/caravel/rtl/__user_project_wrapper.v b/caravel/rtl/__user_project_wrapper.v deleted file mode 100644 index 98ff3a8..0000000 --- a/caravel/rtl/__user_project_wrapper.v +++ /dev/null
@@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -/* - *------------------------------------------------------------- - * - * user_project_wrapper - * - * This wrapper enumerates all of the pins available to the - * user for the user project. - * - * An example user project is provided in this wrapper. The - * example should be removed and replaced with the actual - * user project. - * - *------------------------------------------------------------- - */ - -module user_project_wrapper #( - parameter BITS = 32 -)( -`ifdef USE_POWER_PINS - inout vdda1, // User area 1 3.3V supply - inout vdda2, // User area 2 3.3V supply - inout vssa1, // User area 1 analog ground - inout vssa2, // User area 2 analog ground - inout vccd1, // User area 1 1.8V supply - inout vccd2, // User area 2 1.8v supply - inout vssd1, // User area 1 digital ground - inout vssd2, // User area 2 digital ground -`endif - - // Wishbone Slave ports (WB MI A) - input wb_clk_i, - input wb_rst_i, - input wbs_stb_i, - input wbs_cyc_i, - input wbs_we_i, - input [3:0] wbs_sel_i, - input [31:0] wbs_dat_i, - input [31:0] wbs_adr_i, - output wbs_ack_o, - output [31:0] wbs_dat_o, - - // Logic Analyzer Signals - input [127:0] la_data_in, - output [127:0] la_data_out, - input [127:0] la_oenb, - - // IOs - input [`MPRJ_IO_PADS-1:0] io_in, - output [`MPRJ_IO_PADS-1:0] io_out, - output [`MPRJ_IO_PADS-1:0] io_oeb, - - // Analog (direct connection to GPIO pad---use with caution) - // Note that analog I/O is not available on the 7 lowest-numbered - // GPIO pads, and so the analog_io indexing is offset from the - // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io). - inout [`MPRJ_IO_PADS-10:0] analog_io, - - // Independent clock (on independent integer divider) - input user_clock2, - - // User maskable interrupt signals - output [2:0] user_irq -); - -// Dummy assignments so that we can take it through the openlane flow -`ifdef SIM -// Needed for running GL simulation -assign io_out = 0; -assign io_oeb = 0; -`else -assign io_out = io_in; -`endif - -endmodule // user_project_wrapper
diff --git a/caravel/rtl/caravan.v b/caravel/rtl/caravan.v deleted file mode 100644 index 73c87f1..0000000 --- a/caravel/rtl/caravan.v +++ /dev/null
@@ -1,874 +0,0 @@ -// `default_nettype none -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 -/*--------------------------------------------------------------*/ -/* caravan, a project harness for the Google/SkyWater sky130 */ -/* fabrication process and open source PDK. caravan is an */ -/* alternative architecture to caravel that has simple straight */ -/* through connections replacing the GPIO pads on the top side */ -/* of the padframe. A total of 11 pads are converted from GPIO */ -/* to analog, leaving 27 GPIO. */ -/* */ -/* Copyright 2021 efabless, Inc. */ -/* Written by Tim Edwards, December 2019 */ -/* and Mohamed Shalan, August 2020 */ -/* This file is open source hardware released under the */ -/* Apache 2.0 license. See file LICENSE. */ -/* */ -/*--------------------------------------------------------------*/ - -/*--------------------------------------------------------------*/ -/* Derived types for the array bounds on the two digital and */ -/* two analog pad arrays. As defined above, the sections have */ -/* the number of pads as follows: */ -/* */ -/* DIG2 : 13 GPIO pads */ -/* ANA2 : 6 analog pads */ -/* ANA1 : 5 analog pads */ -/* DIG1 : 14 GPIO pads */ -/* */ -/* This makes a total of 38 pads = `MPRJ_IO_PADS */ -/* The pads are still designated as mprj_io[37:0] around the */ -/* padframe. The SoC core remains the same, so the programming */ -/* of the digital signals remains the same, but the values for */ -/* GPIO 15-25 are not used. */ -/*--------------------------------------------------------------*/ - -`define DIG2_TOP (`MPRJ_IO_PADS - 1) -`define DIG2_BOT (`MPRJ_IO_PADS_1 + `ANALOG_PADS_2) -`define ANA2_TOP (`MPRJ_IO_PADS_1 + `ANALOG_PADS_2 - 1) -`define ANA2_BOT (`MPRJ_IO_PADS_1) -`define ANA1_TOP (`MPRJ_IO_PADS_1 - 1) -`define ANA1_BOT (`MPRJ_IO_PADS_1 - `ANALOG_PADS_1) -`define DIG1_TOP (`MPRJ_IO_PADS_1 - `ANALOG_PADS_1 - 1) -`define DIG1_BOT (0) - -`define MPRJ_DIG_PADS (`MPRJ_IO_PADS - `ANALOG_PADS) - -/*--------------------------------------------------------------*/ -/*--------------------------------------------------------------*/ - -module caravan ( - inout vddio, // Common 3.3V padframe/ESD power - inout vddio_2, // Common 3.3V padframe/ESD power - inout vssio, // Common padframe/ESD ground - inout vssio_2, // Common padframe/ESD ground - inout vdda, // Management 3.3V power - inout vssa, // Common analog ground - inout vccd, // Management/Common 1.8V power - inout vssd, // Common digital ground - inout vdda1, // User area 1 3.3V power - inout vdda1_2, // User area 1 3.3V power - inout vdda2, // User area 2 3.3V power - inout vssa1, // User area 1 analog ground - inout vssa1_2, // User area 1 analog ground - inout vssa2, // User area 2 analog ground - inout vccd1, // User area 1 1.8V power - inout vccd2, // User area 2 1.8V power - inout vssd1, // User area 1 digital ground - inout vssd2, // User area 2 digital ground - - inout gpio, // Used for external LDO control - inout [`MPRJ_IO_PADS-1:0] mprj_io, - output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out, - input clock, // CMOS core clock input, not a crystal - input resetb, - - // Note that only two pins are available on the flash so dual and - // quad flash modes are not available. - - output flash_csb, - output flash_clk, - output flash_io0, - output flash_io1 -); - - //------------------------------------------------------------ - // This value is uniquely defined for each user project. - //------------------------------------------------------------ - parameter USER_PROJECT_ID = 32'h00000000; - - // These pins are overlaid on mprj_io space. They have the function - // below when the management processor is in reset, or in the default - // configuration. They are assigned to uses in the user space by the - // configuration program running off of the SPI flash. Note that even - // when the user has taken control of these pins, they can be restored - // to the original use by setting the resetb pin low. The SPI pins and - // UART pins can be connected directly to an FTDI chip as long as the - // FTDI chip sets these lines to high impedence (input function) at - // all times except when holding the chip in reset. - - // JTAG = mprj_io[0] (inout) - // SDO = mprj_io[1] (output) - // SDI = mprj_io[2] (input) - // CSB = mprj_io[3] (input) - // SCK = mprj_io[4] (input) - // ser_rx = mprj_io[5] (input) - // ser_tx = mprj_io[6] (output) - // irq = mprj_io[7] (input) - - // These pins are reserved for any project that wants to incorporate - // its own processor and flash controller. While a user project can - // technically use any available I/O pins for the purpose, these - // four pins connect to a pass-through mode from the SPI slave (pins - // 1-4 above) so that any SPI flash connected to these specific pins - // can be accessed through the SPI slave even when the processor is in - // reset. - - // user_flash_csb = mprj_io[8] - // user_flash_sck = mprj_io[9] - // user_flash_io0 = mprj_io[10] - // user_flash_io1 = mprj_io[11] - - // One-bit GPIO dedicated to management SoC (outside of user control) - wire gpio_out_core; - wire gpio_in_core; - wire gpio_mode0_core; - wire gpio_mode1_core; - wire gpio_outenb_core; - wire gpio_inenb_core; - - // 27 GPIO pads with full controls - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_inp_dis; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_oeb; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_ib_mode_sel; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_vtrip_sel; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_slow_sel; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_holdover; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_analog_en; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_analog_sel; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_analog_pol; - wire [(`MPRJ_IO_PADS-`ANALOG_PADS)*3-1:0] mprj_io_dm; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_in; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_in_3v3; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_out; - - // User Project Control (user-facing) - // 27 GPIO bidirectional with in/out/oeb and a 3.3V copy of the input - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] user_io_oeb; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] user_io_in; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] user_io_out; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] user_io_in_3v3; - - // 18 direct connections to GPIO for low-frequency, low-voltage analog - wire [`MPRJ_IO_PADS-`ANALOG_PADS-10:0] user_gpio_analog; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-10:0] user_gpio_noesd; - - // 3 power supply ESD clamps for user applications - wire [2:0] user_clamp_high; - wire [2:0] user_clamp_low; - - // 11 core connections to the analog pads - wire [`ANALOG_PADS-1:0] user_analog; - - /* Padframe control signals */ - wire [`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1:0] gpio_serial_link_1; - wire [`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1:0] gpio_serial_link_2; - wire mprj_io_loader_resetn; - wire mprj_io_loader_clock; - wire mprj_io_loader_data_1; /* user1 side serial loader */ - wire mprj_io_loader_data_2; /* user2 side serial loader */ - - // User Project Control management I/O - // There are two types of GPIO connections: - // (1) Full Bidirectional: Management connects to in, out, and oeb - // Uses: JTAG and SDO - // (2) Selectable bidirectional: Management connects to in and out, - // which are tied together. oeb is grounded (oeb from the - // configuration is used) - - // SDI = mprj_io[2] (input) - // CSB = mprj_io[3] (input) - // SCK = mprj_io[4] (input) - // ser_rx = mprj_io[5] (input) - // ser_tx = mprj_io[6] (output) - // irq = mprj_io[7] (input) - - wire [`MPRJ_IO_PADS-1:0] mgmt_io_in; - wire jtag_out, sdo_out; - wire jtag_outenb, sdo_outenb; - wire gpio_flash_io2_out, gpio_flash_io3_out; - - wire [1:0] mgmt_io_nc; /* no-connects */ - - wire clock_core; - - // Power-on-reset signal. The reset pad generates the sense-inverted - // reset at 3.3V. The 1.8V signal and the inverted 1.8V signal are - // derived. - - wire porb_h; - wire porb_l; - wire por_l; - - wire rstb_h; - wire rstb_l; - - wire flash_clk_core, flash_csb_core; - wire flash_clk_oeb_core, flash_csb_oeb_core; - wire flash_clk_ieb_core, flash_csb_ieb_core; - wire flash_io0_oeb_core, flash_io1_oeb_core; - wire flash_io2_oeb_core, flash_io3_oeb_core; - wire flash_io0_ieb_core, flash_io1_ieb_core; - wire flash_io0_do_core, flash_io1_do_core; - wire flash_io0_di_core, flash_io1_di_core; - - chip_io_alt #( - .ANALOG_PADS_1(`ANALOG_PADS_1), - .ANALOG_PADS_2(`ANALOG_PADS_2) - ) padframe ( - `ifndef TOP_ROUTING - // Package Pins - .vddio_pad (vddio), // Common padframe/ESD supply - .vddio_pad2 (vddio_2), - .vssio_pad (vssio), // Common padframe/ESD ground - .vssio_pad2 (vssio_2), - .vccd_pad (vccd), // Common 1.8V supply - .vssd_pad (vssd), // Common digital ground - .vdda_pad (vdda), // Management analog 3.3V supply - .vssa_pad (vssa), // Management analog ground - .vdda1_pad (vdda1), // User area 1 3.3V supply - .vdda1_pad2 (vdda1_2), - .vdda2_pad (vdda2), // User area 2 3.3V supply - .vssa1_pad (vssa1), // User area 1 analog ground - .vssa1_pad2 (vssa1_2), - .vssa2_pad (vssa2), // User area 2 analog ground - .vccd1_pad (vccd1), // User area 1 1.8V supply - .vccd2_pad (vccd2), // User area 2 1.8V supply - .vssd1_pad (vssd1), // User area 1 digital ground - .vssd2_pad (vssd2), // User area 2 digital ground - `endif - - // Core Side Pins - .vddio (vddio_core), - .vssio (vssio_core), - .vdda (vdda_core), - .vssa (vssa_core), - .vccd (vccd_core), - .vssd (vssd_core), - .vdda1 (vdda1_core), - .vdda2 (vdda2_core), - .vssa1 (vssa1_core), - .vssa2 (vssa2_core), - .vccd1 (vccd1_core), - .vccd2 (vccd2_core), - .vssd1 (vssd1_core), - .vssd2 (vssd2_core), - - .gpio(gpio), - .mprj_io(mprj_io), - .clock(clock), - .resetb(resetb), - .flash_csb(flash_csb), - .flash_clk(flash_clk), - .flash_io0(flash_io0), - .flash_io1(flash_io1), - // SoC Core Interface - .porb_h(porb_h), - .por(por_l), - .resetb_core_h(rstb_h), - .clock_core(clock_core), - .gpio_out_core(gpio_out_core), - .gpio_in_core(gpio_in_core), - .gpio_mode0_core(gpio_mode0_core), - .gpio_mode1_core(gpio_mode1_core), - .gpio_outenb_core(gpio_outenb_core), - .gpio_inenb_core(gpio_inenb_core), - .flash_csb_core(flash_csb_core), - .flash_clk_core(flash_clk_core), - .flash_csb_oeb_core(flash_csb_oeb_core), - .flash_clk_oeb_core(flash_clk_oeb_core), - .flash_io0_oeb_core(flash_io0_oeb_core), - .flash_io1_oeb_core(flash_io1_oeb_core), - .flash_csb_ieb_core(flash_csb_ieb_core), - .flash_clk_ieb_core(flash_clk_ieb_core), - .flash_io0_ieb_core(flash_io0_ieb_core), - .flash_io1_ieb_core(flash_io1_ieb_core), - .flash_io0_do_core(flash_io0_do_core), - .flash_io1_do_core(flash_io1_do_core), - .flash_io0_di_core(flash_io0_di_core), - .flash_io1_di_core(flash_io1_di_core), - .mprj_io_in(mprj_io_in), - .mprj_io_in_3v3(mprj_io_in_3v3), - .mprj_io_out(mprj_io_out), - .mprj_io_oeb(mprj_io_oeb), - .mprj_io_inp_dis(mprj_io_inp_dis), - .mprj_io_ib_mode_sel(mprj_io_ib_mode_sel), - .mprj_io_vtrip_sel(mprj_io_vtrip_sel), - .mprj_io_slow_sel(mprj_io_slow_sel), - .mprj_io_holdover(mprj_io_holdover), - .mprj_io_analog_en(mprj_io_analog_en), - .mprj_io_analog_sel(mprj_io_analog_sel), - .mprj_io_analog_pol(mprj_io_analog_pol), - .mprj_io_dm(mprj_io_dm), - .mprj_gpio_analog(user_gpio_analog), - .mprj_gpio_noesd(user_gpio_noesd), - .mprj_analog(user_analog), - .mprj_clamp_high(user_clamp_high), - .mprj_clamp_low(user_clamp_low) - ); - - // SoC core - wire caravel_clk; - wire caravel_clk2; - wire caravel_rstn; - - wire [7:0] spi_ro_config_core; - - // LA signals - wire [127:0] la_data_in_user; // From CPU to MPRJ - wire [127:0] la_data_in_mprj; // From MPRJ to CPU - wire [127:0] la_data_out_mprj; // From CPU to MPRJ - wire [127:0] la_data_out_user; // From MPRJ to CPU - wire [127:0] la_oenb_user; // From CPU to MPRJ - wire [127:0] la_oenb_mprj; // From CPU to MPRJ - wire [127:0] la_iena_mprj; // From CPU only - - wire [2:0] user_irq; // From MPRJ to CPU - wire [2:0] user_irq_core; - wire [2:0] user_irq_ena; - - // WB MI A (User Project) - wire mprj_cyc_o_core; - wire mprj_stb_o_core; - wire mprj_we_o_core; - wire [3:0] mprj_sel_o_core; - wire [31:0] mprj_adr_o_core; - wire [31:0] mprj_dat_o_core; - wire mprj_ack_i_core; - wire [31:0] mprj_dat_i_core; - - // Mask revision - wire [31:0] mask_rev; - - wire mprj_clock; - wire mprj_clock2; - wire mprj_reset; - wire mprj_cyc_o_user; - wire mprj_stb_o_user; - wire mprj_we_o_user; - wire [3:0] mprj_sel_o_user; - wire [31:0] mprj_adr_o_user; - wire [31:0] mprj_dat_o_user; - wire mprj_vcc_pwrgood; - wire mprj2_vcc_pwrgood; - wire mprj_vdd_pwrgood; - wire mprj2_vdd_pwrgood; - - // Storage area - // Management R/W interface - wire [`RAM_BLOCKS-1:0] mgmt_ena; - wire [`RAM_BLOCKS-1:0] mgmt_wen; - wire [(`RAM_BLOCKS*4)-1:0] mgmt_wen_mask; - wire [7:0] mgmt_addr; - wire [31:0] mgmt_wdata; - wire [(`RAM_BLOCKS*32)-1:0] mgmt_rdata; - // Management RO interface - wire mgmt_ena_ro; - wire [7:0] mgmt_addr_ro; - wire [31:0] mgmt_rdata_ro; - - mgmt_core soc ( - `ifdef USE_POWER_PINS - .VPWR(vccd_core), - .VGND(vssd_core), - `endif - // GPIO (1 pin) - .gpio_out_pad(gpio_out_core), - .gpio_in_pad(gpio_in_core), - .gpio_mode0_pad(gpio_mode0_core), - .gpio_mode1_pad(gpio_mode1_core), - .gpio_outenb_pad(gpio_outenb_core), - .gpio_inenb_pad(gpio_inenb_core), - // Primary SPI flash controller - .flash_csb(flash_csb_core), - .flash_clk(flash_clk_core), - .flash_csb_oeb(flash_csb_oeb_core), - .flash_clk_oeb(flash_clk_oeb_core), - .flash_io0_oeb(flash_io0_oeb_core), - .flash_io1_oeb(flash_io1_oeb_core), - .flash_csb_ieb(flash_csb_ieb_core), - .flash_clk_ieb(flash_clk_ieb_core), - .flash_io0_ieb(flash_io0_ieb_core), - .flash_io1_ieb(flash_io1_ieb_core), - .flash_io0_do(flash_io0_do_core), - .flash_io1_do(flash_io1_do_core), - .flash_io0_di(flash_io0_di_core), - .flash_io1_di(flash_io1_di_core), - // Master Reset - .resetb(rstb_l), - .porb(porb_l), - // Clocks and reset - .clock(clock_core), - .core_clk(caravel_clk), - .user_clk(caravel_clk2), - .core_rstn(caravel_rstn), - // IRQ - .user_irq(user_irq), - .user_irq_ena(user_irq_ena), - // Logic Analyzer - .la_input(la_data_in_mprj), - .la_output(la_data_out_mprj), - .la_oenb(la_oenb_mprj), - .la_iena(la_iena_mprj), - // User Project IO Control - .mprj_vcc_pwrgood(mprj_vcc_pwrgood), - .mprj2_vcc_pwrgood(mprj2_vcc_pwrgood), - .mprj_vdd_pwrgood(mprj_vdd_pwrgood), - .mprj2_vdd_pwrgood(mprj2_vdd_pwrgood), - .mprj_io_loader_resetn(mprj_io_loader_resetn), - .mprj_io_loader_clock(mprj_io_loader_clock), - .mprj_io_loader_data_1(mprj_io_loader_data_1), - .mprj_io_loader_data_2(mprj_io_loader_data_2), - .mgmt_in_data(mgmt_io_in), - .mgmt_out_data({gpio_flash_io3_out, gpio_flash_io2_out, - mgmt_io_in[(`MPRJ_IO_PADS-3):2], - mgmt_io_nc}), - .pwr_ctrl_out(pwr_ctrl_out), - .sdo_out(sdo_out), - .sdo_outenb(sdo_outenb), - .jtag_out(jtag_out), - .jtag_outenb(jtag_outenb), - .flash_io2_oeb(flash_io2_oeb_core), - .flash_io3_oeb(flash_io3_oeb_core), - // User Project Slave ports (WB MI A) - .mprj_cyc_o(mprj_cyc_o_core), - .mprj_stb_o(mprj_stb_o_core), - .mprj_we_o(mprj_we_o_core), - .mprj_sel_o(mprj_sel_o_core), - .mprj_adr_o(mprj_adr_o_core), - .mprj_dat_o(mprj_dat_o_core), - .mprj_ack_i(mprj_ack_i_core), - .mprj_dat_i(mprj_dat_i_core), - // mask data - .mask_rev(mask_rev), - // MGMT area R/W interface - .mgmt_ena(mgmt_ena), - .mgmt_wen_mask(mgmt_wen_mask), - .mgmt_wen(mgmt_wen), - .mgmt_addr(mgmt_addr), - .mgmt_wdata(mgmt_wdata), - .mgmt_rdata(mgmt_rdata), - // MGMT area RO interface - .mgmt_ena_ro(mgmt_ena_ro), - .mgmt_addr_ro(mgmt_addr_ro), - .mgmt_rdata_ro(mgmt_rdata_ro) - ); - - /* Clock and reset to user space are passed through a tristate */ - /* buffer like the above, but since they are intended to be */ - /* always active, connect the enable to the logic-1 output from */ - /* the vccd1 domain. */ - - mgmt_protect mgmt_buffers ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - .vccd2(vccd2_core), - .vssd2(vssd2_core), - .vdda1(vdda1_core), - .vssa1(vssa1_core), - .vdda2(vdda2_core), - .vssa2(vssa2_core), - `endif - - .caravel_clk(caravel_clk), - .caravel_clk2(caravel_clk2), - .caravel_rstn(caravel_rstn), - .mprj_cyc_o_core(mprj_cyc_o_core), - .mprj_stb_o_core(mprj_stb_o_core), - .mprj_we_o_core(mprj_we_o_core), - .mprj_sel_o_core(mprj_sel_o_core), - .mprj_adr_o_core(mprj_adr_o_core), - .mprj_dat_o_core(mprj_dat_o_core), - .user_irq_core(user_irq_core), - .la_data_out_core(la_data_out_user), - .la_data_out_mprj(la_data_out_mprj), - .la_data_in_core(la_data_in_user), - .la_data_in_mprj(la_data_in_mprj), - .la_oenb_mprj(la_oenb_mprj), - .la_oenb_core(la_oenb_user), - .la_iena_mprj(la_iena_mprj), - .user_irq_ena(user_irq_ena), - - .user_clock(mprj_clock), - .user_clock2(mprj_clock2), - .user_reset(mprj_reset), - .mprj_cyc_o_user(mprj_cyc_o_user), - .mprj_stb_o_user(mprj_stb_o_user), - .mprj_we_o_user(mprj_we_o_user), - .mprj_sel_o_user(mprj_sel_o_user), - .mprj_adr_o_user(mprj_adr_o_user), - .mprj_dat_o_user(mprj_dat_o_user), - .user_irq(user_irq), - .user1_vcc_powergood(mprj_vcc_pwrgood), - .user2_vcc_powergood(mprj2_vcc_pwrgood), - .user1_vdd_powergood(mprj_vdd_pwrgood), - .user2_vdd_powergood(mprj2_vdd_pwrgood) - ); - - - /*----------------------------------------------*/ - /* Wrapper module around the user project */ - /*----------------------------------------------*/ - - assign user_io_in_3v3 = mprj_io_in_3v3; - - user_analog_project_wrapper mprj ( - `ifdef USE_POWER_PINS - .vdda1(vdda1_core), // User area 1 3.3V power - .vdda2(vdda2_core), // User area 2 3.3V power - .vssa1(vssa1_core), // User area 1 analog ground - .vssa2(vssa2_core), // User area 2 analog ground - .vccd1(vccd1_core), // User area 1 1.8V power - .vccd2(vccd2_core), // User area 2 1.8V power - .vssd1(vssd1_core), // User area 1 digital ground - .vssd2(vssd2_core), // User area 2 digital ground - `endif - - .wb_clk_i(mprj_clock), - .wb_rst_i(mprj_reset), - // MGMT SoC Wishbone Slave - .wbs_cyc_i(mprj_cyc_o_user), - .wbs_stb_i(mprj_stb_o_user), - .wbs_we_i(mprj_we_o_user), - .wbs_sel_i(mprj_sel_o_user), - .wbs_adr_i(mprj_adr_o_user), - .wbs_dat_i(mprj_dat_o_user), - .wbs_ack_o(mprj_ack_i_core), - .wbs_dat_o(mprj_dat_i_core), - // Logic Analyzer - .la_data_in(la_data_in_user), - .la_data_out(la_data_out_user), - .la_oenb(la_oenb_user), - // IO Pads - .io_in (user_io_in), - .io_in_3v3 (user_io_in_3v3), - .io_out(user_io_out), - .io_oeb(user_io_oeb), - .gpio_analog(user_gpio_analog), - .gpio_noesd(user_gpio_noesd), - .io_clamp_high(user_clamp_high), - .io_clamp_low(user_clamp_low), - .io_analog(user_analog), - // Independent clock - .user_clock2(mprj_clock2), - // IRQ - .user_irq(user_irq_core) - ); - - /*--------------------------------------*/ - /* End user project instantiation */ - /*--------------------------------------*/ - - wire [`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1:0] gpio_serial_link_1_shifted; - wire [`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1:0] gpio_serial_link_2_shifted; - - assign gpio_serial_link_1_shifted = {gpio_serial_link_1[`MPRJ_IO_PADS_1-`ANALOG_PADS_1-2:0], - mprj_io_loader_data_1}; - // Note that serial_link_2 is backwards compared to serial_link_1, so it - // shifts in the other direction. - assign gpio_serial_link_2_shifted = {mprj_io_loader_data_2, - gpio_serial_link_2[`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1:1]}; - - // Propagating clock and reset to mitigate timing and fanout issues - wire [`MPRJ_IO_PADS_1-1:0] gpio_clock_1; - wire [`MPRJ_IO_PADS_2-1:0] gpio_clock_2; - wire [`MPRJ_IO_PADS_1-1:0] gpio_resetn_1; - wire [`MPRJ_IO_PADS_2-1:0] gpio_resetn_2; - wire [`MPRJ_IO_PADS_1-6:0] gpio_clock_1_shifted; - wire [`MPRJ_IO_PADS_2-7:0] gpio_clock_2_shifted; - wire [`MPRJ_IO_PADS_1-6:0] gpio_resetn_1_shifted; - wire [`MPRJ_IO_PADS_2-7:0] gpio_resetn_2_shifted; - - assign gpio_clock_1_shifted = {gpio_clock_1[`MPRJ_IO_PADS_1-`ANALOG_PADS_1-2:0], - mprj_io_loader_clock}; - assign gpio_clock_2_shifted = {mprj_io_loader_clock, - gpio_clock_2[`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1:1]}; - assign gpio_resetn_1_shifted = {gpio_resetn_1[`MPRJ_IO_PADS_1-`ANALOG_PADS_1-2:0], - mprj_io_loader_resetn}; - assign gpio_resetn_2_shifted = {mprj_io_loader_resetn, - gpio_resetn_2[`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1:1]}; - - // Each control block sits next to an I/O pad in the user area. - // It gets input through a serial chain from the previous control - // block and passes it to the next control block. Due to the nature - // of the shift register, bits are presented in reverse, as the first - // bit in ends up as the last bit of the last I/O pad control block. - - // There are two types of block; the first two and the last two - // are configured to be full bidirectional under control of the - // management Soc (JTAG and SDO for the first two; flash_io2 and - // flash_io3 for the last two). The rest are configured to be default - // (input). Note that the first two and last two are the ones closest - // to the management SoC on either side, which minimizes the wire length - // of the extra signals those pads need. - - /* First two GPIOs (JTAG and SDO) */ - gpio_control_block #( - .DM_INIT(`DM_INIT), // Mode = output, strong up/down - .OENB_INIT(`OENB_INIT) // Enable output signaling from wire - ) gpio_control_bidir_1 [1:0] ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - `endif - - // Management Soc-facing signals - - .resetn(gpio_resetn_1_shifted[1:0]), - .serial_clock(gpio_clock_1_shifted[1:0]), - - .resetn_out(gpio_resetn_1[1:0]), - .serial_clock_out(gpio_clock_1[1:0]), - - .mgmt_gpio_in(mgmt_io_in[1:0]), - .mgmt_gpio_out({sdo_out, jtag_out}), - .mgmt_gpio_oeb({sdo_outenb, jtag_outenb}), - - .one(), - .zero(), - - // Serial data chain for pad configuration - .serial_data_in(gpio_serial_link_1_shifted[1:0]), - .serial_data_out(gpio_serial_link_1[1:0]), - - // User-facing signals - .user_gpio_out(user_io_out[1:0]), - .user_gpio_oeb(user_io_oeb[1:0]), - .user_gpio_in(user_io_in[1:0]), - - // Pad-facing signals (Pad GPIOv2) - .pad_gpio_inenb(mprj_io_inp_dis[1:0]), - .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[1:0]), - .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[1:0]), - .pad_gpio_slow_sel(mprj_io_slow_sel[1:0]), - .pad_gpio_holdover(mprj_io_holdover[1:0]), - .pad_gpio_ana_en(mprj_io_analog_en[1:0]), - .pad_gpio_ana_sel(mprj_io_analog_sel[1:0]), - .pad_gpio_ana_pol(mprj_io_analog_pol[1:0]), - .pad_gpio_dm(mprj_io_dm[5:0]), - .pad_gpio_outenb(mprj_io_oeb[1:0]), - .pad_gpio_out(mprj_io_out[1:0]), - .pad_gpio_in(mprj_io_in[1:0]) - ); - - /* Section 1 GPIOs (GPIO 0 to 18) */ - wire [`MPRJ_IO_PADS_1-`ANALOG_PADS_1-3:0] one_loop1; - gpio_control_block gpio_control_in_1 [`MPRJ_IO_PADS_1-`ANALOG_PADS_1-3:0] ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - `endif - - // Management Soc-facing signals - - .resetn(gpio_resetn_1_shifted[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .serial_clock(gpio_clock_1_shifted[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - - .resetn_out(gpio_resetn_1[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .serial_clock_out(gpio_clock_1[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - - .mgmt_gpio_in(mgmt_io_in[`DIG1_TOP:2]), - .mgmt_gpio_out(mgmt_io_in[`DIG1_TOP:2]), - .mgmt_gpio_oeb(one_loop1), - - .one(one_loop1), - .zero(), - - // Serial data chain for pad configuration - .serial_data_in(gpio_serial_link_1_shifted[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .serial_data_out(gpio_serial_link_1[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - - // User-facing signals - .user_gpio_out(user_io_out[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .user_gpio_oeb(user_io_oeb[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .user_gpio_in(user_io_in[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - - // Pad-facing signals (Pad GPIOv2) - .pad_gpio_inenb(mprj_io_inp_dis[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_slow_sel(mprj_io_slow_sel[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_holdover(mprj_io_holdover[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_ana_en(mprj_io_analog_en[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_ana_sel(mprj_io_analog_sel[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_ana_pol(mprj_io_analog_pol[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_dm(mprj_io_dm[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)*3-1:6]), - .pad_gpio_outenb(mprj_io_oeb[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_out(mprj_io_out[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]), - .pad_gpio_in(mprj_io_in[(`MPRJ_IO_PADS_1-`ANALOG_PADS_1-1):2]) - ); - - /* Last two GPIOs (flash_io2 and flash_io3) */ - gpio_control_block #( - .DM_INIT(`DM_INIT), // Mode = output, strong up/down - .OENB_INIT(`OENB_INIT) // Enable output signaling from wire - ) gpio_control_bidir_2 [1:0] ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - `endif - - // Management Soc-facing signals - - .resetn(gpio_resetn_1_shifted[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1):(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-2)]), - .serial_clock(gpio_clock_1_shifted[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1):(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-2)]), - - .resetn_out(gpio_resetn_1[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1):(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-2)]), - .serial_clock_out(gpio_clock_1[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1):(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-2)]), - - .mgmt_gpio_in(mgmt_io_in[(`DIG2_TOP):(`DIG2_TOP-1)]), - .mgmt_gpio_out({gpio_flash_io3_out, gpio_flash_io2_out}), - .mgmt_gpio_oeb({flash_io3_oeb_core, flash_io2_oeb_core}), - - .one(), - .zero(), - - // Serial data chain for pad configuration - .serial_data_in(gpio_serial_link_2_shifted[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1):(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-2)]), - .serial_data_out(gpio_serial_link_2[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-1):(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-2)]), - - // User-facing signals - .user_gpio_out(user_io_out[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .user_gpio_oeb(user_io_oeb[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .user_gpio_in(user_io_in[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - - // Pad-facing signals (Pad GPIOv2) - .pad_gpio_inenb(mprj_io_inp_dis[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_slow_sel(mprj_io_slow_sel[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_holdover(mprj_io_holdover[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_ana_en(mprj_io_analog_en[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_ana_sel(mprj_io_analog_sel[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_ana_pol(mprj_io_analog_pol[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_dm(mprj_io_dm[(`MPRJ_DIG_PADS*3-1):(`MPRJ_DIG_PADS*3-6)]), - .pad_gpio_outenb(mprj_io_oeb[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_out(mprj_io_out[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]), - .pad_gpio_in(mprj_io_in[(`MPRJ_DIG_PADS-1):(`MPRJ_DIG_PADS-2)]) - ); - - /* Section 2 GPIOs (GPIO 19 to 37) */ - wire [`MPRJ_IO_PADS_2-`ANALOG_PADS_2-3:0] one_loop2; - gpio_control_block gpio_control_in_2 [`MPRJ_IO_PADS_2-`ANALOG_PADS_2-3:0] ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - `endif - - // Management Soc-facing signals - - .resetn(gpio_resetn_1_shifted[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-3):0]), - .serial_clock(gpio_clock_1_shifted[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-3):0]), - - .resetn_out(gpio_resetn_1[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-3):0]), - .serial_clock_out(gpio_clock_1[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-3):0]), - - .mgmt_gpio_in(mgmt_io_in[(`DIG2_TOP-2):`DIG2_BOT]), - .mgmt_gpio_out(mgmt_io_in[(`DIG2_TOP-2):`DIG2_BOT]), - .mgmt_gpio_oeb(one_loop2), - - .one(one_loop2), - .zero(), - - // Serial data chain for pad configuration - .serial_data_in(gpio_serial_link_2_shifted[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-3):0]), - .serial_data_out(gpio_serial_link_2[(`MPRJ_IO_PADS_2-`ANALOG_PADS_2-3):0]), - - // User-facing signals - .user_gpio_out(user_io_out[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .user_gpio_oeb(user_io_oeb[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .user_gpio_in(user_io_in[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - - // Pad-facing signals (Pad GPIOv2) - .pad_gpio_inenb(mprj_io_inp_dis[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_slow_sel(mprj_io_slow_sel[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_holdover(mprj_io_holdover[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_ana_en(mprj_io_analog_en[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_ana_sel(mprj_io_analog_sel[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_ana_pol(mprj_io_analog_pol[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_dm(mprj_io_dm[((`MPRJ_DIG_PADS)*3-7):((`MPRJ_IO_PADS_1-`ANALOG_PADS_1)*3)]), - .pad_gpio_outenb(mprj_io_oeb[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_out(mprj_io_out[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]), - .pad_gpio_in(mprj_io_in[(`MPRJ_DIG_PADS-3):(`MPRJ_IO_PADS_1-`ANALOG_PADS_1)]) - ); - - user_id_programming #( - .USER_PROJECT_ID(USER_PROJECT_ID) - ) user_id_value ( - `ifdef USE_POWER_PINS - .VPWR(vccd_core), - .VGND(vssd_core), - `endif - .mask_rev(mask_rev) - ); - - // Power-on-reset circuit - simple_por por ( - `ifdef USE_POWER_PINS - .vdd3v3(vddio_core), - .vdd1v8(vccd_core), - .vss(vssio_core), - `endif - .porb_h(porb_h), - .porb_l(porb_l), - .por_l(por_l) - ); - - // XRES (chip input pin reset) reset level converter - sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped rstb_level ( - `ifdef USE_POWER_PINS - .VPWR(vddio_core), - .LVPWR(vccd_core), - .VGND(vssio_core), - `endif - .A(rstb_h), - .X(rstb_l) - ); - - // Storage area - storage storage( - `ifdef USE_POWER_PINS - .VPWR(vccd_core), - .VGND(vssd_core), - `endif - .mgmt_clk(caravel_clk), - .mgmt_ena(mgmt_ena), - .mgmt_wen(mgmt_wen), - .mgmt_wen_mask(mgmt_wen_mask), - .mgmt_addr(mgmt_addr), - .mgmt_wdata(mgmt_wdata), - .mgmt_rdata(mgmt_rdata), - // Management RO interface - .mgmt_ena_ro(mgmt_ena_ro), - .mgmt_addr_ro(mgmt_addr_ro), - .mgmt_rdata_ro(mgmt_rdata_ro) - ); - -endmodule -// `default_nettype wire
diff --git a/caravel/rtl/caravan_netlists.v b/caravel/rtl/caravan_netlists.v deleted file mode 100644 index 60ff673..0000000 --- a/caravel/rtl/caravan_netlists.v +++ /dev/null
@@ -1,93 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`timescale 1 ns / 1 ps - -`define UNIT_DELAY #1 -`define USE_POWER_PINS - -`ifdef SIM - -`include "defines.v" -`include "pads.v" - -/* NOTE: Need to pass the PDK root directory to iverilog with option -I */ -`ifdef EF_STYLE // efabless style pdk installation; mainly for open galaxy users - `include "libs.ref/verilog/sky130_fd_io/sky130_fd_io.v" - `include "libs.ref/verilog/sky130_fd_io/sky130_ef_io.v" - `include "libs.ref/verilog/sky130_fd_io/sky130_ef_io__gpiov2_pad_wrapped.v" - `include "libs.ref/verilog/sky130_fd_io/sky130_ef_io__analog_pad.v" - - `include "libs.ref/verilog/sky130_fd_sc_hd/primitives.v" - `include "libs.ref/verilog/sky130_fd_sc_hd/sky130_fd_sc_hd.v" - `include "libs.ref/verilog/sky130_fd_sc_hvl/primitives.v" - `include "libs.ref/verilog/sky130_fd_sc_hvl/sky130_fd_sc_hvl.v" -`else - `include "libs.ref/sky130_fd_io/verilog/sky130_fd_io.v" - `include "libs.ref/sky130_fd_io/verilog/sky130_ef_io.v" - `include "libs.ref/sky130_fd_io/verilog/sky130_ef_io__gpiov2_pad_wrapped.v" - `include "libs.ref/sky130_fd_io/verilog/sky130_ef_io__analog_pad.v" - - `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v" - `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v" - `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v" - `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v" -`endif - -`ifdef GL - // Assume default net type to be wire because GL netlists don't have the wire definitions - `default_nettype wire - `include "gl/mgmt_core.v" - `include "gl/digital_pll.v" - `include "gl/DFFRAM.v" - `include "gl/storage.v" - `include "gl/user_id_programming.v" - `include "gl/chip_io_alt.v" - `include "gl/mprj_logic_high.v" - `include "gl/mprj2_logic_high.v" - `include "gl/mgmt_protect.v" - `include "gl/mgmt_protect_hv.v" - `include "gl/gpio_logic_high.v" - `include "gl/gpio_control_block.v" - `include "gl/sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped.v" - `include "gl/caravan.v" -`else - `include "mgmt_soc.v" - `include "housekeeping_spi.v" - `include "caravel_clocking.v" - `include "mgmt_core.v" - `include "digital_pll.v" - `include "DFFRAM.v" - `include "DFFRAMBB.v" - `include "storage.v" - `include "user_id_programming.v" - `include "clock_div.v" - `include "storage_bridge_wb.v" - `include "mprj_io.v" - `include "chip_io_alt.v" - `include "mprj_logic_high.v" - `include "mprj2_logic_high.v" - `include "mgmt_protect.v" - `include "mgmt_protect_hv.v" - `include "gpio_control_block.v" - `include "gpio_logic_high.v" - `include "sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped.v" - `include "caravan.v" -`endif - -`include "simple_por.v" -`include "sram_1rw1r_32_256_8_sky130.v" - -`endif
diff --git a/caravel/rtl/caravel.v b/caravel/rtl/caravel.v deleted file mode 100644 index eb8ad2d..0000000 --- a/caravel/rtl/caravel.v +++ /dev/null
@@ -1,818 +0,0 @@ -// `default_nettype none -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 -/*--------------------------------------------------------------*/ -/* caravel, a project harness for the Google/SkyWater sky130 */ -/* fabrication process and open source PDK */ -/* */ -/* Copyright 2020 efabless, Inc. */ -/* Written by Tim Edwards, December 2019 */ -/* and Mohamed Shalan, August 2020 */ -/* This file is open source hardware released under the */ -/* Apache 2.0 license. See file LICENSE. */ -/* */ -/*--------------------------------------------------------------*/ - -module caravel ( - inout vddio, // Common 3.3V padframe/ESD power - inout vddio_2, // Common 3.3V padframe/ESD power - inout vssio, // Common padframe/ESD ground - inout vssio_2, // Common padframe/ESD ground - inout vdda, // Management 3.3V power - inout vssa, // Common analog ground - inout vccd, // Management/Common 1.8V power - inout vssd, // Common digital ground - inout vdda1, // User area 1 3.3V power - inout vdda1_2, // User area 1 3.3V power - inout vdda2, // User area 2 3.3V power - inout vssa1, // User area 1 analog ground - inout vssa1_2, // User area 1 analog ground - inout vssa2, // User area 2 analog ground - inout vccd1, // User area 1 1.8V power - inout vccd2, // User area 2 1.8V power - inout vssd1, // User area 1 digital ground - inout vssd2, // User area 2 digital ground - - inout gpio, // Used for external LDO control - inout [`MPRJ_IO_PADS-1:0] mprj_io, - output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out, - input clock, // CMOS core clock input, not a crystal - input resetb, - - // Note that only two pins are available on the flash so dual and - // quad flash modes are not available. - - output flash_csb, - output flash_clk, - output flash_io0, - output flash_io1 -); - - //------------------------------------------------------------ - // This value is uniquely defined for each user project. - //------------------------------------------------------------ - parameter USER_PROJECT_ID = 32'h00000000; - - // These pins are overlaid on mprj_io space. They have the function - // below when the management processor is in reset, or in the default - // configuration. They are assigned to uses in the user space by the - // configuration program running off of the SPI flash. Note that even - // when the user has taken control of these pins, they can be restored - // to the original use by setting the resetb pin low. The SPI pins and - // UART pins can be connected directly to an FTDI chip as long as the - // FTDI chip sets these lines to high impedence (input function) at - // all times except when holding the chip in reset. - - // JTAG = mprj_io[0] (inout) - // SDO = mprj_io[1] (output) - // SDI = mprj_io[2] (input) - // CSB = mprj_io[3] (input) - // SCK = mprj_io[4] (input) - // ser_rx = mprj_io[5] (input) - // ser_tx = mprj_io[6] (output) - // irq = mprj_io[7] (input) - - // These pins are reserved for any project that wants to incorporate - // its own processor and flash controller. While a user project can - // technically use any available I/O pins for the purpose, these - // four pins connect to a pass-through mode from the SPI slave (pins - // 1-4 above) so that any SPI flash connected to these specific pins - // can be accessed through the SPI slave even when the processor is in - // reset. - - // user_flash_csb = mprj_io[8] - // user_flash_sck = mprj_io[9] - // user_flash_io0 = mprj_io[10] - // user_flash_io1 = mprj_io[11] - - // One-bit GPIO dedicated to management SoC (outside of user control) - wire gpio_out_core; - wire gpio_in_core; - wire gpio_mode0_core; - wire gpio_mode1_core; - wire gpio_outenb_core; - wire gpio_inenb_core; - - // User Project Control (pad-facing) - wire [`MPRJ_IO_PADS-1:0] mprj_io_inp_dis; - wire [`MPRJ_IO_PADS-1:0] mprj_io_oeb; - wire [`MPRJ_IO_PADS-1:0] mprj_io_ib_mode_sel; - wire [`MPRJ_IO_PADS-1:0] mprj_io_vtrip_sel; - wire [`MPRJ_IO_PADS-1:0] mprj_io_slow_sel; - wire [`MPRJ_IO_PADS-1:0] mprj_io_holdover; - wire [`MPRJ_IO_PADS-1:0] mprj_io_analog_en; - wire [`MPRJ_IO_PADS-1:0] mprj_io_analog_sel; - wire [`MPRJ_IO_PADS-1:0] mprj_io_analog_pol; - wire [`MPRJ_IO_PADS*3-1:0] mprj_io_dm; - wire [`MPRJ_IO_PADS-1:0] mprj_io_in; - wire [`MPRJ_IO_PADS-1:0] mprj_io_out; - - // User Project Control (user-facing) - wire [`MPRJ_IO_PADS-1:0] user_io_oeb; - wire [`MPRJ_IO_PADS-1:0] user_io_in; - wire [`MPRJ_IO_PADS-1:0] user_io_out; - wire [`MPRJ_IO_PADS-10:0] user_analog_io; - - /* Padframe control signals */ - wire [`MPRJ_IO_PADS_1-1:0] gpio_serial_link_1; - wire [`MPRJ_IO_PADS_2-1:0] gpio_serial_link_2; - wire mprj_io_loader_resetn; - wire mprj_io_loader_clock; - wire mprj_io_loader_data_1; /* user1 side serial loader */ - wire mprj_io_loader_data_2; /* user2 side serial loader */ - - // User Project Control management I/O - // There are two types of GPIO connections: - // (1) Full Bidirectional: Management connects to in, out, and oeb - // Uses: JTAG and SDO - // (2) Selectable bidirectional: Management connects to in and out, - // which are tied together. oeb is grounded (oeb from the - // configuration is used) - - // SDI = mprj_io[2] (input) - // CSB = mprj_io[3] (input) - // SCK = mprj_io[4] (input) - // ser_rx = mprj_io[5] (input) - // ser_tx = mprj_io[6] (output) - // irq = mprj_io[7] (input) - - wire [`MPRJ_IO_PADS-1:0] mgmt_io_in; - wire jtag_out, sdo_out; - wire jtag_outenb, sdo_outenb; - wire gpio_flash_io2_out, gpio_flash_io3_out; - - wire [1:0] mgmt_io_nc; /* no-connects */ - - wire clock_core; - - // Power-on-reset signal. The reset pad generates the sense-inverted - // reset at 3.3V. The 1.8V signal and the inverted 1.8V signal are - // derived. - - wire porb_h; - wire porb_l; - wire por_l; - - wire rstb_h; - wire rstb_l; - - wire flash_clk_core, flash_csb_core; - wire flash_clk_oeb_core, flash_csb_oeb_core; - wire flash_clk_ieb_core, flash_csb_ieb_core; - wire flash_io0_oeb_core, flash_io1_oeb_core; - wire flash_io2_oeb_core, flash_io3_oeb_core; - wire flash_io0_ieb_core, flash_io1_ieb_core; - wire flash_io0_do_core, flash_io1_do_core; - wire flash_io0_di_core, flash_io1_di_core; - - chip_io padframe( - `ifndef TOP_ROUTING - // Package Pins - .vddio_pad (vddio), // Common padframe/ESD supply - .vddio_pad2 (vddio_2), - .vssio_pad (vssio), // Common padframe/ESD ground - .vssio_pad2 (vssio_2), - .vccd_pad (vccd), // Common 1.8V supply - .vssd_pad (vssd), // Common digital ground - .vdda_pad (vdda), // Management analog 3.3V supply - .vssa_pad (vssa), // Management analog ground - .vdda1_pad (vdda1), // User area 1 3.3V supply - .vdda1_pad2 (vdda1_2), - .vdda2_pad (vdda2), // User area 2 3.3V supply - .vssa1_pad (vssa1), // User area 1 analog ground - .vssa1_pad2 (vssa1_2), - .vssa2_pad (vssa2), // User area 2 analog ground - .vccd1_pad (vccd1), // User area 1 1.8V supply - .vccd2_pad (vccd2), // User area 2 1.8V supply - .vssd1_pad (vssd1), // User area 1 digital ground - .vssd2_pad (vssd2), // User area 2 digital ground - `endif - // Core Side Pins - .vddio (vddio_core), - .vssio (vssio_core), - .vdda (vdda_core), - .vssa (vssa_core), - .vccd (vccd_core), - .vssd (vssd_core), - .vdda1 (vdda1_core), - .vdda2 (vdda2_core), - .vssa1 (vssa1_core), - .vssa2 (vssa2_core), - .vccd1 (vccd1_core), - .vccd2 (vccd2_core), - .vssd1 (vssd1_core), - .vssd2 (vssd2_core), - - .gpio(gpio), - .mprj_io(mprj_io), - .clock(clock), - .resetb(resetb), - .flash_csb(flash_csb), - .flash_clk(flash_clk), - .flash_io0(flash_io0), - .flash_io1(flash_io1), - // SoC Core Interface - .porb_h(porb_h), - .por(por_l), - .resetb_core_h(rstb_h), - .clock_core(clock_core), - .gpio_out_core(gpio_out_core), - .gpio_in_core(gpio_in_core), - .gpio_mode0_core(gpio_mode0_core), - .gpio_mode1_core(gpio_mode1_core), - .gpio_outenb_core(gpio_outenb_core), - .gpio_inenb_core(gpio_inenb_core), - .flash_csb_core(flash_csb_core), - .flash_clk_core(flash_clk_core), - .flash_csb_oeb_core(flash_csb_oeb_core), - .flash_clk_oeb_core(flash_clk_oeb_core), - .flash_io0_oeb_core(flash_io0_oeb_core), - .flash_io1_oeb_core(flash_io1_oeb_core), - .flash_csb_ieb_core(flash_csb_ieb_core), - .flash_clk_ieb_core(flash_clk_ieb_core), - .flash_io0_ieb_core(flash_io0_ieb_core), - .flash_io1_ieb_core(flash_io1_ieb_core), - .flash_io0_do_core(flash_io0_do_core), - .flash_io1_do_core(flash_io1_do_core), - .flash_io0_di_core(flash_io0_di_core), - .flash_io1_di_core(flash_io1_di_core), - .mprj_io_in(mprj_io_in), - .mprj_io_out(mprj_io_out), - .mprj_io_oeb(mprj_io_oeb), - .mprj_io_inp_dis(mprj_io_inp_dis), - .mprj_io_ib_mode_sel(mprj_io_ib_mode_sel), - .mprj_io_vtrip_sel(mprj_io_vtrip_sel), - .mprj_io_slow_sel(mprj_io_slow_sel), - .mprj_io_holdover(mprj_io_holdover), - .mprj_io_analog_en(mprj_io_analog_en), - .mprj_io_analog_sel(mprj_io_analog_sel), - .mprj_io_analog_pol(mprj_io_analog_pol), - .mprj_io_dm(mprj_io_dm), - .mprj_analog_io(user_analog_io) - ); - - // SoC core - wire caravel_clk; - wire caravel_clk2; - wire caravel_rstn; - - wire [7:0] spi_ro_config_core; - - // LA signals - wire [127:0] la_data_in_user; // From CPU to MPRJ - wire [127:0] la_data_in_mprj; // From MPRJ to CPU - wire [127:0] la_data_out_mprj; // From CPU to MPRJ - wire [127:0] la_data_out_user; // From MPRJ to CPU - wire [127:0] la_oenb_user; // From CPU to MPRJ - wire [127:0] la_oenb_mprj; // From CPU to MPRJ - wire [127:0] la_iena_mprj; // From CPU only - wire [2:0] user_irq; // From MRPJ to CPU - wire [2:0] user_irq_core; - wire [2:0] user_irq_ena; - - // WB MI A (User Project) - wire mprj_cyc_o_core; - wire mprj_stb_o_core; - wire mprj_we_o_core; - wire [3:0] mprj_sel_o_core; - wire [31:0] mprj_adr_o_core; - wire [31:0] mprj_dat_o_core; - wire mprj_ack_i_core; - wire [31:0] mprj_dat_i_core; - - // WB MI B (xbar) - wire xbar_cyc_o_core; - wire xbar_stb_o_core; - wire xbar_we_o_core; - wire [3:0] xbar_sel_o_core; - wire [31:0] xbar_adr_o_core; - wire [31:0] xbar_dat_o_core; - wire xbar_ack_i_core; - wire [31:0] xbar_dat_i_core; - - // Mask revision - wire [31:0] mask_rev; - - wire mprj_clock; - wire mprj_clock2; - wire mprj_reset; - wire mprj_cyc_o_user; - wire mprj_stb_o_user; - wire mprj_we_o_user; - wire [3:0] mprj_sel_o_user; - wire [31:0] mprj_adr_o_user; - wire [31:0] mprj_dat_o_user; - wire mprj_vcc_pwrgood; - wire mprj2_vcc_pwrgood; - wire mprj_vdd_pwrgood; - wire mprj2_vdd_pwrgood; - - // Storage area - // Management R/W interface - wire [`RAM_BLOCKS-1:0] mgmt_ena; - wire [`RAM_BLOCKS-1:0] mgmt_wen; - wire [(`RAM_BLOCKS*4)-1:0] mgmt_wen_mask; - wire [7:0] mgmt_addr; - wire [31:0] mgmt_wdata; - wire [(`RAM_BLOCKS*32)-1:0] mgmt_rdata; - // Management RO interface - wire mgmt_ena_ro; - wire [7:0] mgmt_addr_ro; - wire [31:0] mgmt_rdata_ro; - - mgmt_core soc ( - `ifdef USE_POWER_PINS - .VPWR(vccd_core), - .VGND(vssd_core), - `endif - // GPIO (1 pin) - .gpio_out_pad(gpio_out_core), - .gpio_in_pad(gpio_in_core), - .gpio_mode0_pad(gpio_mode0_core), - .gpio_mode1_pad(gpio_mode1_core), - .gpio_outenb_pad(gpio_outenb_core), - .gpio_inenb_pad(gpio_inenb_core), - // Primary SPI flash controller - .flash_csb(flash_csb_core), - .flash_clk(flash_clk_core), - .flash_csb_oeb(flash_csb_oeb_core), - .flash_clk_oeb(flash_clk_oeb_core), - .flash_io0_oeb(flash_io0_oeb_core), - .flash_io1_oeb(flash_io1_oeb_core), - .flash_csb_ieb(flash_csb_ieb_core), - .flash_clk_ieb(flash_clk_ieb_core), - .flash_io0_ieb(flash_io0_ieb_core), - .flash_io1_ieb(flash_io1_ieb_core), - .flash_io0_do(flash_io0_do_core), - .flash_io1_do(flash_io1_do_core), - .flash_io0_di(flash_io0_di_core), - .flash_io1_di(flash_io1_di_core), - // Master Reset - .resetb(rstb_l), - .porb(porb_l), - // Clocks and reset - .clock(clock_core), - .core_clk(caravel_clk), - .user_clk(caravel_clk2), - .core_rstn(caravel_rstn), - // IRQ - .user_irq(user_irq), - .user_irq_ena(user_irq_ena), - // Logic Analyzer - .la_input(la_data_in_mprj), - .la_output(la_data_out_mprj), - .la_oenb(la_oenb_mprj), - .la_iena(la_iena_mprj), - // User Project IO Control - .mprj_vcc_pwrgood(mprj_vcc_pwrgood), - .mprj2_vcc_pwrgood(mprj2_vcc_pwrgood), - .mprj_vdd_pwrgood(mprj_vdd_pwrgood), - .mprj2_vdd_pwrgood(mprj2_vdd_pwrgood), - .mprj_io_loader_resetn(mprj_io_loader_resetn), - .mprj_io_loader_clock(mprj_io_loader_clock), - .mprj_io_loader_data_1(mprj_io_loader_data_1), - .mprj_io_loader_data_2(mprj_io_loader_data_2), - .mgmt_in_data(mgmt_io_in), - .mgmt_out_data({gpio_flash_io3_out, gpio_flash_io2_out, - mgmt_io_in[(`MPRJ_IO_PADS-3):2], mgmt_io_nc}), - .pwr_ctrl_out(pwr_ctrl_out), - .sdo_out(sdo_out), - .sdo_outenb(sdo_outenb), - .jtag_out(jtag_out), - .jtag_outenb(jtag_outenb), - .flash_io2_oeb(flash_io2_oeb_core), - .flash_io3_oeb(flash_io3_oeb_core), - // User Project Slave ports (WB MI A) - .mprj_cyc_o(mprj_cyc_o_core), - .mprj_stb_o(mprj_stb_o_core), - .mprj_we_o(mprj_we_o_core), - .mprj_sel_o(mprj_sel_o_core), - .mprj_adr_o(mprj_adr_o_core), - .mprj_dat_o(mprj_dat_o_core), - .mprj_ack_i(mprj_ack_i_core), - .mprj_dat_i(mprj_dat_i_core), - // mask data - .mask_rev(mask_rev), - // MGMT area R/W interface - .mgmt_ena(mgmt_ena), - .mgmt_wen_mask(mgmt_wen_mask), - .mgmt_wen(mgmt_wen), - .mgmt_addr(mgmt_addr), - .mgmt_wdata(mgmt_wdata), - .mgmt_rdata(mgmt_rdata), - // MGMT area RO interface - .mgmt_ena_ro(mgmt_ena_ro), - .mgmt_addr_ro(mgmt_addr_ro), - .mgmt_rdata_ro(mgmt_rdata_ro) - ); - - /* Clock and reset to user space are passed through a tristate */ - /* buffer like the above, but since they are intended to be */ - /* always active, connect the enable to the logic-1 output from */ - /* the vccd1 domain. */ - - mgmt_protect mgmt_buffers ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - .vccd2(vccd2_core), - .vssd2(vssd2_core), - .vdda1(vdda1_core), - .vssa1(vssa1_core), - .vdda2(vdda2_core), - .vssa2(vssa2_core), - `endif - .caravel_clk(caravel_clk), - .caravel_clk2(caravel_clk2), - .caravel_rstn(caravel_rstn), - .mprj_cyc_o_core(mprj_cyc_o_core), - .mprj_stb_o_core(mprj_stb_o_core), - .mprj_we_o_core(mprj_we_o_core), - .mprj_sel_o_core(mprj_sel_o_core), - .mprj_adr_o_core(mprj_adr_o_core), - .mprj_dat_o_core(mprj_dat_o_core), - .user_irq_core(user_irq_core), - .la_data_out_core(la_data_out_user), - .la_data_out_mprj(la_data_out_mprj), - .la_data_in_core(la_data_in_user), - .la_data_in_mprj(la_data_in_mprj), - .la_oenb_mprj(la_oenb_mprj), - .la_oenb_core(la_oenb_user), - .la_iena_mprj(la_iena_mprj), - .user_irq_ena(user_irq_ena), - - .user_clock(mprj_clock), - .user_clock2(mprj_clock2), - .user_reset(mprj_reset), - .mprj_cyc_o_user(mprj_cyc_o_user), - .mprj_stb_o_user(mprj_stb_o_user), - .mprj_we_o_user(mprj_we_o_user), - .mprj_sel_o_user(mprj_sel_o_user), - .mprj_adr_o_user(mprj_adr_o_user), - .mprj_dat_o_user(mprj_dat_o_user), - .user_irq(user_irq), - .user1_vcc_powergood(mprj_vcc_pwrgood), - .user2_vcc_powergood(mprj2_vcc_pwrgood), - .user1_vdd_powergood(mprj_vdd_pwrgood), - .user2_vdd_powergood(mprj2_vdd_pwrgood) - ); - - - /*----------------------------------------------*/ - /* Wrapper module around the user project */ - /*----------------------------------------------*/ - - user_project_wrapper mprj ( - `ifdef USE_POWER_PINS - .vdda1(vdda1_core), // User area 1 3.3V power - .vdda2(vdda2_core), // User area 2 3.3V power - .vssa1(vssa1_core), // User area 1 analog ground - .vssa2(vssa2_core), // User area 2 analog ground - .vccd1(vccd1_core), // User area 1 1.8V power - .vccd2(vccd2_core), // User area 2 1.8V power - .vssd1(vssd1_core), // User area 1 digital ground - .vssd2(vssd2_core), // User area 2 digital ground - `endif - - .wb_clk_i(mprj_clock), - .wb_rst_i(mprj_reset), - // MGMT SoC Wishbone Slave - .wbs_cyc_i(mprj_cyc_o_user), - .wbs_stb_i(mprj_stb_o_user), - .wbs_we_i(mprj_we_o_user), - .wbs_sel_i(mprj_sel_o_user), - .wbs_adr_i(mprj_adr_o_user), - .wbs_dat_i(mprj_dat_o_user), - .wbs_ack_o(mprj_ack_i_core), - .wbs_dat_o(mprj_dat_i_core), - // Logic Analyzer - .la_data_in(la_data_in_user), - .la_data_out(la_data_out_user), - .la_oenb(la_oenb_user), - // IO Pads - .io_in (user_io_in), - .io_out(user_io_out), - .io_oeb(user_io_oeb), - .analog_io(user_analog_io), - // Independent clock - .user_clock2(mprj_clock2), - // IRQ - .user_irq(user_irq_core) - ); - - /*--------------------------------------*/ - /* End user project instantiation */ - /*--------------------------------------*/ - - wire [`MPRJ_IO_PADS_1-1:0] gpio_serial_link_1_shifted; - wire [`MPRJ_IO_PADS_2-1:0] gpio_serial_link_2_shifted; - - assign gpio_serial_link_1_shifted = {gpio_serial_link_1[`MPRJ_IO_PADS_1-2:0], - mprj_io_loader_data_1}; - // Note that serial_link_2 is backwards compared to serial_link_1, so it - // shifts in the other direction. - assign gpio_serial_link_2_shifted = {mprj_io_loader_data_2, - gpio_serial_link_2[`MPRJ_IO_PADS_2-1:1]}; - - // Propagating clock and reset to mitigate timing and fanout issues - wire [`MPRJ_IO_PADS_1-1:0] gpio_clock_1; - wire [`MPRJ_IO_PADS_2-1:0] gpio_clock_2; - wire [`MPRJ_IO_PADS_1-1:0] gpio_resetn_1; - wire [`MPRJ_IO_PADS_2-1:0] gpio_resetn_2; - wire [`MPRJ_IO_PADS_1-1:0] gpio_clock_1_shifted; - wire [`MPRJ_IO_PADS_2-1:0] gpio_clock_2_shifted; - wire [`MPRJ_IO_PADS_1-1:0] gpio_resetn_1_shifted; - wire [`MPRJ_IO_PADS_2-1:0] gpio_resetn_2_shifted; - - assign gpio_clock_1_shifted = {gpio_clock_1[`MPRJ_IO_PADS_1-2:0], - mprj_io_loader_clock}; - assign gpio_clock_2_shifted = {mprj_io_loader_clock, - gpio_clock_2[`MPRJ_IO_PADS_2-1:1]}; - assign gpio_resetn_1_shifted = {gpio_resetn_1[`MPRJ_IO_PADS_1-2:0], - mprj_io_loader_resetn}; - assign gpio_resetn_2_shifted = {mprj_io_loader_resetn, - gpio_resetn_2[`MPRJ_IO_PADS_2-1:1]}; - - // Each control block sits next to an I/O pad in the user area. - // It gets input through a serial chain from the previous control - // block and passes it to the next control block. Due to the nature - // of the shift register, bits are presented in reverse, as the first - // bit in ends up as the last bit of the last I/O pad control block. - - // There are two types of block; the first two and the last two - // are configured to be full bidirectional under control of the - // management Soc (JTAG and SDO for the first two; flash_io2 and - // flash_io3 for the last two). The rest are configured to be default - // (input). Note that the first two and last two are the ones closest - // to the management SoC on either side, which minimizes the wire length - // of the extra signals those pads need. - - /* First two GPIOs (JTAG and SDO) */ - gpio_control_block #( - .DM_INIT(`DM_INIT), // Mode = output, strong up/down - .OENB_INIT(`OENB_INIT) // Enable output signaling from wire - ) gpio_control_bidir_1 [1:0] ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - `endif - - // Management Soc-facing signals - - .resetn(gpio_resetn_1_shifted[1:0]), - .serial_clock(gpio_clock_1_shifted[1:0]), - - .resetn_out(gpio_resetn_1[1:0]), - .serial_clock_out(gpio_clock_1[1:0]), - - .mgmt_gpio_in(mgmt_io_in[1:0]), - .mgmt_gpio_out({sdo_out, jtag_out}), - .mgmt_gpio_oeb({sdo_outenb, jtag_outenb}), - - .one(), - .zero(), - - // Serial data chain for pad configuration - .serial_data_in(gpio_serial_link_1_shifted[1:0]), - .serial_data_out(gpio_serial_link_1[1:0]), - - // User-facing signals - .user_gpio_out(user_io_out[1:0]), - .user_gpio_oeb(user_io_oeb[1:0]), - .user_gpio_in(user_io_in[1:0]), - - // Pad-facing signals (Pad GPIOv2) - .pad_gpio_inenb(mprj_io_inp_dis[1:0]), - .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[1:0]), - .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[1:0]), - .pad_gpio_slow_sel(mprj_io_slow_sel[1:0]), - .pad_gpio_holdover(mprj_io_holdover[1:0]), - .pad_gpio_ana_en(mprj_io_analog_en[1:0]), - .pad_gpio_ana_sel(mprj_io_analog_sel[1:0]), - .pad_gpio_ana_pol(mprj_io_analog_pol[1:0]), - .pad_gpio_dm(mprj_io_dm[5:0]), - .pad_gpio_outenb(mprj_io_oeb[1:0]), - .pad_gpio_out(mprj_io_out[1:0]), - .pad_gpio_in(mprj_io_in[1:0]) - ); - - /* Section 1 GPIOs (GPIO 0 to 18) */ - wire [`MPRJ_IO_PADS_1-1:2] one_loop1; - gpio_control_block gpio_control_in_1 [`MPRJ_IO_PADS_1-3:0] ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - `endif - - // Management Soc-facing signals - - .resetn(gpio_resetn_1_shifted[(`MPRJ_IO_PADS_1-1):2]), - .serial_clock(gpio_clock_1_shifted[(`MPRJ_IO_PADS_1-1):2]), - - .resetn_out(gpio_resetn_1[(`MPRJ_IO_PADS_1-1):2]), - .serial_clock_out(gpio_clock_1[(`MPRJ_IO_PADS_1-1):2]), - - .mgmt_gpio_in(mgmt_io_in[(`MPRJ_IO_PADS_1-1):2]), - .mgmt_gpio_out(mgmt_io_in[(`MPRJ_IO_PADS_1-1):2]), - .mgmt_gpio_oeb(one_loop1), - - .one(one_loop1), - .zero(), - - // Serial data chain for pad configuration - .serial_data_in(gpio_serial_link_1_shifted[(`MPRJ_IO_PADS_1-1):2]), - .serial_data_out(gpio_serial_link_1[(`MPRJ_IO_PADS_1-1):2]), - - // User-facing signals - .user_gpio_out(user_io_out[(`MPRJ_IO_PADS_1-1):2]), - .user_gpio_oeb(user_io_oeb[(`MPRJ_IO_PADS_1-1):2]), - .user_gpio_in(user_io_in[(`MPRJ_IO_PADS_1-1):2]), - - // Pad-facing signals (Pad GPIOv2) - .pad_gpio_inenb(mprj_io_inp_dis[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_slow_sel(mprj_io_slow_sel[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_holdover(mprj_io_holdover[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_ana_en(mprj_io_analog_en[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_ana_sel(mprj_io_analog_sel[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_ana_pol(mprj_io_analog_pol[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_dm(mprj_io_dm[(`MPRJ_IO_PADS_1*3-1):6]), - .pad_gpio_outenb(mprj_io_oeb[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_out(mprj_io_out[(`MPRJ_IO_PADS_1-1):2]), - .pad_gpio_in(mprj_io_in[(`MPRJ_IO_PADS_1-1):2]) - ); - - /* Last two GPIOs (flash_io2 and flash_io3) */ - gpio_control_block #( - .DM_INIT(`DM_INIT), // Mode = output, strong up/down - .OENB_INIT(`OENB_INIT) // Enable output signaling from wire - ) gpio_control_bidir_2 [1:0] ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - `endif - - // Management Soc-facing signals - - .resetn(gpio_resetn_1_shifted[(`MPRJ_IO_PADS_2-1):(`MPRJ_IO_PADS_2-2)]), - .serial_clock(gpio_clock_1_shifted[(`MPRJ_IO_PADS_2-1):(`MPRJ_IO_PADS_2-2)]), - - .resetn_out(gpio_resetn_1[(`MPRJ_IO_PADS_2-1):(`MPRJ_IO_PADS_2-2)]), - .serial_clock_out(gpio_clock_1[(`MPRJ_IO_PADS_2-1):(`MPRJ_IO_PADS_2-2)]), - - .mgmt_gpio_in(mgmt_io_in[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .mgmt_gpio_out({gpio_flash_io3_out, gpio_flash_io2_out}), - .mgmt_gpio_oeb({flash_io3_oeb_core, flash_io2_oeb_core}), - - .one(), - .zero(), - - // Serial data chain for pad configuration - .serial_data_in(gpio_serial_link_2_shifted[(`MPRJ_IO_PADS_2-1):(`MPRJ_IO_PADS_2-2)]), - .serial_data_out(gpio_serial_link_2[(`MPRJ_IO_PADS_2-1):(`MPRJ_IO_PADS_2-2)]), - - // User-facing signals - .user_gpio_out(user_io_out[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .user_gpio_oeb(user_io_oeb[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .user_gpio_in(user_io_in[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - - // Pad-facing signals (Pad GPIOv2) - .pad_gpio_inenb(mprj_io_inp_dis[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_slow_sel(mprj_io_slow_sel[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_holdover(mprj_io_holdover[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_ana_en(mprj_io_analog_en[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_ana_sel(mprj_io_analog_sel[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_ana_pol(mprj_io_analog_pol[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_dm(mprj_io_dm[(`MPRJ_IO_PADS*3-1):(`MPRJ_IO_PADS*3-6)]), - .pad_gpio_outenb(mprj_io_oeb[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_out(mprj_io_out[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]), - .pad_gpio_in(mprj_io_in[(`MPRJ_IO_PADS-1):(`MPRJ_IO_PADS-2)]) - ); - - /* Section 2 GPIOs (GPIO 19 to 37) */ - wire [`MPRJ_IO_PADS_2-3:0] one_loop2; - gpio_control_block gpio_control_in_2 [`MPRJ_IO_PADS_2-3:0] ( - `ifdef USE_POWER_PINS - .vccd(vccd_core), - .vssd(vssd_core), - .vccd1(vccd1_core), - .vssd1(vssd1_core), - `endif - - // Management Soc-facing signals - - .resetn(gpio_resetn_1_shifted[(`MPRJ_IO_PADS_2-3):0]), - .serial_clock(gpio_clock_1_shifted[(`MPRJ_IO_PADS_2-3):0]), - - .resetn_out(gpio_resetn_1[(`MPRJ_IO_PADS_2-3):0]), - .serial_clock_out(gpio_clock_1[(`MPRJ_IO_PADS_2-3):0]), - - .mgmt_gpio_in(mgmt_io_in[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .mgmt_gpio_out(mgmt_io_in[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .mgmt_gpio_oeb(one_loop2), - - .one(one_loop2), - .zero(), - - // Serial data chain for pad configuration - .serial_data_in(gpio_serial_link_2_shifted[(`MPRJ_IO_PADS_2-3):0]), - .serial_data_out(gpio_serial_link_2[(`MPRJ_IO_PADS_2-3):0]), - - // User-facing signals - .user_gpio_out(user_io_out[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .user_gpio_oeb(user_io_oeb[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .user_gpio_in(user_io_in[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - - // Pad-facing signals (Pad GPIOv2) - .pad_gpio_inenb(mprj_io_inp_dis[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_slow_sel(mprj_io_slow_sel[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_holdover(mprj_io_holdover[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_ana_en(mprj_io_analog_en[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_ana_sel(mprj_io_analog_sel[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_ana_pol(mprj_io_analog_pol[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_dm(mprj_io_dm[(`MPRJ_IO_PADS*3-7):(`MPRJ_IO_PADS_1*3)]), - .pad_gpio_outenb(mprj_io_oeb[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_out(mprj_io_out[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]), - .pad_gpio_in(mprj_io_in[(`MPRJ_IO_PADS-3):(`MPRJ_IO_PADS_1)]) - ); - - user_id_programming #( - .USER_PROJECT_ID(USER_PROJECT_ID) - ) user_id_value ( - `ifdef USE_POWER_PINS - .VPWR(vccd_core), - .VGND(vssd_core), - `endif - .mask_rev(mask_rev) - ); - - // Power-on-reset circuit - simple_por por ( - `ifdef USE_POWER_PINS - .vdd3v3(vddio_core), - .vdd1v8(vccd_core), - .vss(vssio_core), - `endif - .porb_h(porb_h), - .porb_l(porb_l), - .por_l(por_l) - ); - - // XRES (chip input pin reset) reset level converter - sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped rstb_level ( - `ifdef USE_POWER_PINS - .VPWR(vddio_core), - .LVPWR(vccd_core), - .LVGND(vssd_core), - .VGND(vssio_core), - `endif - .A(rstb_h), - .X(rstb_l) - ); - - // Storage area - storage storage( - `ifdef USE_POWER_PINS - .VPWR(vccd_core), - .VGND(vssd_core), - `endif - .mgmt_clk(caravel_clk), - .mgmt_ena(mgmt_ena), - .mgmt_wen(mgmt_wen), - .mgmt_wen_mask(mgmt_wen_mask), - .mgmt_addr(mgmt_addr), - .mgmt_wdata(mgmt_wdata), - .mgmt_rdata(mgmt_rdata), - // Management RO interface - .mgmt_ena_ro(mgmt_ena_ro), - .mgmt_addr_ro(mgmt_addr_ro), - .mgmt_rdata_ro(mgmt_rdata_ro) - ); - -endmodule -// `default_nettype wire
diff --git a/caravel/rtl/caravel_clocking.v b/caravel/rtl/caravel_clocking.v deleted file mode 100644 index cc0af25..0000000 --- a/caravel/rtl/caravel_clocking.v +++ /dev/null
@@ -1,111 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -// This routine synchronizes the - -module caravel_clocking( -`ifdef USE_POWER_PINS - input vdd1v8, - input vss, -`endif - input resetb, // Master (negative sense) reset - input ext_clk_sel, // 0=use PLL clock, 1=use external (pad) clock - input ext_clk, // External pad (slow) clock - input pll_clk, // Internal PLL (fast) clock - input pll_clk90, // Internal PLL (fast) clock, 90 degree phase - input [2:0] sel, // Select clock divider value (0=thru, 1=divide-by-2, etc.) - input [2:0] sel2, // Select clock divider value for 90 degree phase divided clock - input ext_reset, // Positive sense reset from housekeeping SPI. - output core_clk, // Output core clock - output user_clk, // Output user (secondary) clock - output resetb_sync // Output propagated and buffered reset -); - - wire pll_clk_sel; - wire pll_clk_divided; - wire pll_clk90_divided; - wire core_ext_clk; - reg use_pll_first; - reg use_pll_second; - reg ext_clk_syncd_pre; - reg ext_clk_syncd; - - assign pll_clk_sel = ~ext_clk_sel; - - // Note that this implementation does not guard against switching to - // the PLL clock if the PLL clock is not present. - - always @(posedge pll_clk or negedge resetb) begin - if (resetb == 1'b0) begin - use_pll_first <= 1'b0; - use_pll_second <= 1'b0; - ext_clk_syncd <= 1'b0; - end else begin - use_pll_first <= pll_clk_sel; - use_pll_second <= use_pll_first; - ext_clk_syncd_pre <= ext_clk; // Sync ext_clk to pll_clk - ext_clk_syncd <= ext_clk_syncd_pre; // Do this twice (resolve metastability) - end - end - - // Apply PLL clock divider - - clock_div #( - .SIZE(3) - ) divider ( - .in(pll_clk), - .out(pll_clk_divided), - .N(sel), - .resetb(resetb) - ); - - // Secondary PLL clock divider for user space access - - clock_div #( - .SIZE(3) - ) divider2 ( - .in(pll_clk90), - .out(pll_clk90_divided), - .N(sel2), - .resetb(resetb) - ); - - - // Multiplex the clock output - - assign core_ext_clk = (use_pll_first) ? ext_clk_syncd : ext_clk; - assign core_clk = (use_pll_second) ? pll_clk_divided : core_ext_clk; - assign user_clk = (use_pll_second) ? pll_clk90_divided : core_ext_clk; - - // Reset assignment. "reset" comes from POR, while "ext_reset" - // comes from standalone SPI (and is normally zero unless - // activated from the SPI). - - // Staged-delay reset - reg [2:0] reset_delay; - - always @(posedge core_clk or negedge resetb) begin - if (resetb == 1'b0) begin - reset_delay <= 3'b111; - end else begin - reset_delay <= {1'b0, reset_delay[2:1]}; - end - end - - assign resetb_sync = ~(reset_delay[0] | ext_reset); - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/caravel_netlists.v b/caravel/rtl/caravel_netlists.v deleted file mode 100644 index 1330104..0000000 --- a/caravel/rtl/caravel_netlists.v +++ /dev/null
@@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`timescale 1 ns / 1 ps - -`define UNIT_DELAY #1 -`define USE_POWER_PINS - -`ifdef SIM - -`include "defines.v" -`include "pads.v" - -/* NOTE: Need to pass the PDK root directory to iverilog with option -I */ - -`ifdef EF_STYLE - `include "libs.ref/verilog/sky130_fd_io/sky130_fd_io.v" - `include "libs.ref/verilog/sky130_fd_io/sky130_ef_io.v" - `include "libs.ref/verilog/sky130_fd_io/sky130_ef_io__gpiov2_pad_wrapped.v" - - `include "libs.ref/verilog/sky130_fd_sc_hd/primitives.v" - `include "libs.ref/verilog/sky130_fd_sc_hd/sky130_fd_sc_hd.v" - `include "libs.ref/verilog/sky130_fd_sc_hvl/primitives.v" - `include "libs.ref/verilog/sky130_fd_sc_hvl/sky130_fd_sc_hvl.v" -`else - `include "libs.ref/sky130_fd_io/verilog/sky130_fd_io.v" - `include "libs.ref/sky130_fd_io/verilog/sky130_ef_io.v" - `include "libs.ref/sky130_fd_io/verilog/sky130_ef_io__gpiov2_pad_wrapped.v" - - `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v" - `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v" - `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v" - `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v" -`endif - -`ifdef GL - `include "gl/mgmt_core.v" - `include "gl/digital_pll.v" - `include "gl/DFFRAM.v" - `include "gl/storage.v" - `include "gl/user_id_programming.v" - `include "gl/chip_io.v" - `include "gl/mprj_logic_high.v" - `include "gl/mprj2_logic_high.v" - `include "gl/mgmt_protect.v" - `include "gl/mgmt_protect_hv.v" - `include "gl/gpio_control_block.v" - `include "gl/gpio_logic_high.v" - `include "gl/sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped.v" - `include "gl/caravel.v" -`else - `include "mgmt_soc.v" - `include "housekeeping_spi.v" - `include "caravel_clocking.v" - `include "mgmt_core.v" - `include "digital_pll.v" - `include "DFFRAM.v" - `include "DFFRAMBB.v" - `include "storage.v" - `include "user_id_programming.v" - `include "clock_div.v" - `include "storage_bridge_wb.v" - `include "mprj_io.v" - `include "chip_io.v" - `include "mprj_logic_high.v" - `include "mprj2_logic_high.v" - `include "mgmt_protect.v" - `include "mgmt_protect_hv.v" - `include "gpio_control_block.v" - `include "gpio_logic_high.v" - `include "sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped.v" - `include "caravel.v" -`endif - -`include "simple_por.v" -`include "sram_1rw1r_32_256_8_sky130.v" - -`endif
diff --git a/caravel/rtl/chip_io.v b/caravel/rtl/chip_io.v deleted file mode 100644 index 39d2ac6..0000000 --- a/caravel/rtl/chip_io.v +++ /dev/null
@@ -1,444 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -// `default_nettype none -module chip_io( - // Package Pins - inout vddio_pad, // Common padframe/ESD supply - inout vddio_pad2, - inout vssio_pad, // Common padframe/ESD ground - inout vssio_pad2, - inout vccd_pad, // Common 1.8V supply - inout vssd_pad, // Common digital ground - inout vdda_pad, // Management analog 3.3V supply - inout vssa_pad, // Management analog ground - inout vdda1_pad, // User area 1 3.3V supply - inout vdda1_pad2, - inout vdda2_pad, // User area 2 3.3V supply - inout vssa1_pad, // User area 1 analog ground - inout vssa1_pad2, - inout vssa2_pad, // User area 2 analog ground - inout vccd1_pad, // User area 1 1.8V supply - inout vccd2_pad, // User area 2 1.8V supply - inout vssd1_pad, // User area 1 digital ground - inout vssd2_pad, // User area 2 digital ground - - // Core Side - inout vddio, // Common padframe/ESD supply - inout vssio, // Common padframe/ESD ground - inout vccd, // Common 1.8V supply - inout vssd, // Common digital ground - inout vdda, // Management analog 3.3V supply - inout vssa, // Management analog ground - inout vdda1, // User area 1 3.3V supply - inout vdda2, // User area 2 3.3V supply - inout vssa1, // User area 1 analog ground - inout vssa2, // User area 2 analog ground - inout vccd1, // User area 1 1.8V supply - inout vccd2, // User area 2 1.8V supply - inout vssd1, // User area 1 digital ground - inout vssd2, // User area 2 digital ground - - inout gpio, - input clock, - input resetb, - output flash_csb, - output flash_clk, - inout flash_io0, - inout flash_io1, - // Chip Core Interface - input porb_h, - input por, - output resetb_core_h, - output clock_core, - input gpio_out_core, - output gpio_in_core, - input gpio_mode0_core, - input gpio_mode1_core, - input gpio_outenb_core, - input gpio_inenb_core, - input flash_csb_core, - input flash_clk_core, - input flash_csb_oeb_core, - input flash_clk_oeb_core, - input flash_io0_oeb_core, - input flash_io1_oeb_core, - input flash_csb_ieb_core, - input flash_clk_ieb_core, - input flash_io0_ieb_core, - input flash_io1_ieb_core, - input flash_io0_do_core, - input flash_io1_do_core, - output flash_io0_di_core, - output flash_io1_di_core, - // User project IOs - inout [`MPRJ_IO_PADS-1:0] mprj_io, - input [`MPRJ_IO_PADS-1:0] mprj_io_out, - input [`MPRJ_IO_PADS-1:0] mprj_io_oeb, - input [`MPRJ_IO_PADS-1:0] mprj_io_inp_dis, - input [`MPRJ_IO_PADS-1:0] mprj_io_ib_mode_sel, - input [`MPRJ_IO_PADS-1:0] mprj_io_vtrip_sel, - input [`MPRJ_IO_PADS-1:0] mprj_io_slow_sel, - input [`MPRJ_IO_PADS-1:0] mprj_io_holdover, - input [`MPRJ_IO_PADS-1:0] mprj_io_analog_en, - input [`MPRJ_IO_PADS-1:0] mprj_io_analog_sel, - input [`MPRJ_IO_PADS-1:0] mprj_io_analog_pol, - input [`MPRJ_IO_PADS*3-1:0] mprj_io_dm, - output [`MPRJ_IO_PADS-1:0] mprj_io_in, - // User project direct access to gpio pad connections for analog - // (all but the lowest-numbered 7 pads) - inout [`MPRJ_IO_PADS-10:0] mprj_analog_io -); - - // To be considered: Master hold signal on all user pads (?) - // For now, set holdh_n to 1 (NOTE: This is in the 3.3V domain) - // and setting enh to porb_h. - - wire [`MPRJ_IO_PADS-1:0] mprj_io_hldh_n; - wire [`MPRJ_IO_PADS-1:0] mprj_io_enh; - - assign mprj_io_hldh_n = {`MPRJ_IO_PADS{vddio}}; - assign mprj_io_enh = {`MPRJ_IO_PADS{porb_h}}; - - wire analog_a, analog_b; - wire vddio_q, vssio_q; - - // Instantiate power and ground pads for management domain - // 12 pads: vddio, vssio, vdda, vssa, vccd, vssd - // One each HV and LV clamp. - - // HV clamps connect between one HV power rail and one ground - // LV clamps have two clamps connecting between any two LV power - // rails and grounds, and one back-to-back diode which connects - // between the first LV clamp ground and any other ground. - - sky130_ef_io__vddio_hvc_clamped_pad \mgmt_vddio_hvclamp_pad[0] ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDIO(vddio) -`else - ,.VDDIO_PAD(vddio_pad) -`endif - ); - - // lies in user area 2 - sky130_ef_io__vddio_hvc_clamped_pad \mgmt_vddio_hvclamp_pad[1] ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDIO(vddio) -`else - ,.VDDIO_PAD(vddio_pad2) -`endif - ); - - sky130_ef_io__vdda_hvc_clamped_pad mgmt_vdda_hvclamp_pad ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDA(vdda) -`else - ,.VDDA_PAD(vdda_pad) -`endif - ); - - sky130_ef_io__vccd_lvc_clamped_pad mgmt_vccd_lvclamp_pad ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VCCD(vccd) -`else - ,.VCCD_PAD(vccd_pad) -`endif - ); - - sky130_ef_io__vssio_hvc_clamped_pad \mgmt_vssio_hvclamp_pad[0] ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSIO(vssio) -`else - ,.VSSIO_PAD(vssio_pad) -`endif - ); - - sky130_ef_io__vssio_hvc_clamped_pad \mgmt_vssio_hvclamp_pad[1] ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSIO(vssio) -`else - ,.VSSIO_PAD(vssio_pad2) -`endif - ); - - sky130_ef_io__vssa_hvc_clamped_pad mgmt_vssa_hvclamp_pad ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSA(vssa) -`else - ,.VSSA_PAD(vssa_pad) -`endif - ); - - sky130_ef_io__vssd_lvc_clamped_pad mgmt_vssd_lvclmap_pad ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSD(vssd) -`else - ,.VSSD_PAD(vssd_pad) -`endif - ); - - // Instantiate power and ground pads for user 1 domain - // 8 pads: vdda, vssa, vccd, vssd; One each HV and LV clamp. - - sky130_ef_io__vdda_hvc_clamped_pad \user1_vdda_hvclamp_pad[0] ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDA(vdda1) -`else - ,.VDDA_PAD(vdda1_pad) -`endif - ); - - sky130_ef_io__vdda_hvc_clamped_pad \user1_vdda_hvclamp_pad[1] ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDA(vdda1) -`else - ,.VDDA_PAD(vdda1_pad2) -`endif - ); - - sky130_ef_io__vccd_lvc_clamped2_pad user1_vccd_lvclamp_pad ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VCCD(vccd1) -`else - ,.VCCD_PAD(vccd1_pad) -`endif - ); - - sky130_ef_io__vssa_hvc_clamped_pad \user1_vssa_hvclamp_pad[0] ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSA(vssa1) -`else - ,.VSSA_PAD(vssa1_pad) -`endif - ); - - - sky130_ef_io__vssa_hvc_clamped_pad \user1_vssa_hvclamp_pad[1] ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSA(vssa1) -`else - ,.VSSA_PAD(vssa1_pad2) -`endif - ); - - sky130_ef_io__vssd_lvc_clamped2_pad user1_vssd_lvclmap_pad ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSD(vssd1) -`else - ,.VSSD_PAD(vssd1_pad) -`endif - ); - - // Instantiate power and ground pads for user 2 domain - // 8 pads: vdda, vssa, vccd, vssd; One each HV and LV clamp. - - sky130_ef_io__vdda_hvc_clamped_pad user2_vdda_hvclamp_pad ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDA(vdda2) -`else - ,.VDDA_PAD(vdda2_pad) -`endif - ); - - sky130_ef_io__vccd_lvc_clamped2_pad user2_vccd_lvclamp_pad ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VCCD(vccd2) -`else - ,.VCCD_PAD(vccd2_pad) -`endif - ); - - sky130_ef_io__vssa_hvc_clamped_pad user2_vssa_hvclamp_pad ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSA(vssa2) -`else - ,.VSSA_PAD(vssa2_pad) -`endif - ); - - sky130_ef_io__vssd_lvc_clamped2_pad user2_vssd_lvclmap_pad ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSD(vssd2) -`else - ,.VSSD_PAD(vssd2_pad) -`endif - ); - - wire [2:0] dm_all = - {gpio_mode1_core, gpio_mode1_core, gpio_mode0_core}; - wire[2:0] flash_io0_mode = - {flash_io0_ieb_core, flash_io0_ieb_core, flash_io0_oeb_core}; - wire[2:0] flash_io1_mode = - {flash_io1_ieb_core, flash_io1_ieb_core, flash_io1_oeb_core}; - - // Management clock input pad - `INPUT_PAD(clock, clock_core); - - // Management GPIO pad - `INOUT_PAD( - gpio, gpio_in_core, gpio_out_core, - gpio_inenb_core, gpio_outenb_core, dm_all); - - // Management Flash SPI pads - `INOUT_PAD( - flash_io0, flash_io0_di_core, flash_io0_do_core, - flash_io0_ieb_core, flash_io0_oeb_core, flash_io0_mode); - `INOUT_PAD( - flash_io1, flash_io1_di_core, flash_io1_do_core, - flash_io1_ieb_core, flash_io1_oeb_core, flash_io1_mode); - - `OUTPUT_PAD(flash_csb, flash_csb_core, flash_csb_ieb_core, flash_csb_oeb_core); - `OUTPUT_PAD(flash_clk, flash_clk_core, flash_clk_ieb_core, flash_clk_oeb_core); - - // NOTE: The analog_out pad from the raven chip has been replaced by - // the digital reset input resetb on caravel due to the lack of an on-board - // power-on-reset circuit. The XRES pad is used for providing a glitch- - // free reset. - - wire xresloop; - sky130_fd_io__top_xres4v2 resetb_pad ( - `MGMT_ABUTMENT_PINS - `ifndef TOP_ROUTING - ,.PAD(resetb), - `endif - .TIE_WEAK_HI_H(xresloop), // Loop-back connection to pad through pad_a_esd_h - .TIE_HI_ESD(), - .TIE_LO_ESD(), - .PAD_A_ESD_H(xresloop), - .XRES_H_N(resetb_core_h), - .DISABLE_PULLUP_H(vssio), // 0 = enable pull-up on reset pad - .ENABLE_H(porb_h), // Power-on-reset - .EN_VDDIO_SIG_H(vssio), // No idea. - .INP_SEL_H(vssio), // 1 = use filt_in_h else filter the pad input - .FILT_IN_H(vssio), // Alternate input for glitch filter - .PULLUP_H(vssio), // Pullup connection for alternate filter input - .ENABLE_VDDIO(vccd) - ); - - // Corner cells (These are overlay cells; it is not clear what is normally - // supposed to go under them.) - - sky130_ef_io__corner_pad mgmt_corner [1:0] ( -`ifndef TOP_ROUTING - .VSSIO(vssio), - .VDDIO(vddio), - .VDDIO_Q(vddio_q), - .VSSIO_Q(vssio_q), - .AMUXBUS_A(analog_a), - .AMUXBUS_B(analog_b), - .VSSD(vssd), - .VSSA(vssa), - .VSWITCH(vddio), - .VDDA(vdda), - .VCCD(vccd), - .VCCHIB(vccd) -`else - .VCCHIB() -`endif - - ); - sky130_ef_io__corner_pad user1_corner ( -`ifndef TOP_ROUTING - .VSSIO(vssio), - .VDDIO(vddio), - .VDDIO_Q(vddio_q), - .VSSIO_Q(vssio_q), - .AMUXBUS_A(analog_a), - .AMUXBUS_B(analog_b), - .VSSD(vssd1), - .VSSA(vssa1), - .VSWITCH(vddio), - .VDDA(vdda1), - .VCCD(vccd1), - .VCCHIB(vccd) -`else - .VCCHIB() -`endif - ); - sky130_ef_io__corner_pad user2_corner ( -`ifndef TOP_ROUTING - .VSSIO(vssio), - .VDDIO(vddio), - .VDDIO_Q(vddio_q), - .VSSIO_Q(vssio_q), - .AMUXBUS_A(analog_a), - .AMUXBUS_B(analog_b), - .VSSD(vssd2), - .VSSA(vssa2), - .VSWITCH(vddio), - .VDDA(vdda2), - .VCCD(vccd2), - .VCCHIB(vccd) -`else - .VCCHIB() -`endif - ); - - mprj_io mprj_pads( - .vddio(vddio), - .vssio(vssio), - .vccd(vccd), - .vssd(vssd), - .vdda1(vdda1), - .vdda2(vdda2), - .vssa1(vssa1), - .vssa2(vssa2), - .vccd1(vccd1), - .vccd2(vccd2), - .vssd1(vssd1), - .vssd2(vssd2), - .vddio_q(vddio_q), - .vssio_q(vssio_q), - .analog_a(analog_a), - .analog_b(analog_b), - .porb_h(porb_h), - .io(mprj_io), - .io_out(mprj_io_out), - .oeb(mprj_io_oeb), - .hldh_n(mprj_io_hldh_n), - .enh(mprj_io_enh), - .inp_dis(mprj_io_inp_dis), - .ib_mode_sel(mprj_io_ib_mode_sel), - .vtrip_sel(mprj_io_vtrip_sel), - .holdover(mprj_io_holdover), - .slow_sel(mprj_io_slow_sel), - .analog_en(mprj_io_analog_en), - .analog_sel(mprj_io_analog_sel), - .analog_pol(mprj_io_analog_pol), - .dm(mprj_io_dm), - .io_in(mprj_io_in), - .analog_io(mprj_analog_io) - ); - -endmodule -// `default_nettype wire
diff --git a/caravel/rtl/chip_io_alt.v b/caravel/rtl/chip_io_alt.v deleted file mode 100644 index 9e05c01..0000000 --- a/caravel/rtl/chip_io_alt.v +++ /dev/null
@@ -1,525 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -// `default_nettype none - -/* Alternative padframe that removes the GPIO from the top row, */ -/* replacing them with un-overlaid power pads which have a */ -/* direct connection from pad to core. */ - -/* For convenience, all of the original GPIO signals remain */ -/* defined in the I/O list, although some are not connected. */ - -/* ANALOG_PADS_1 = Number of GPIO pads in the user 1 section */ -/* that are replaced by straight-through analog */ -/* ANALOG_PADS_2 = Number of GPIO pads in the user 2 section */ -/* that are replaced by straight-through analog */ - -module chip_io_alt #( - parameter ANALOG_PADS_1 = 5, - parameter ANALOG_PADS_2 = 6 -) ( - // Package Pins - inout vddio_pad, // Common padframe/ESD supply - inout vddio_pad2, // Common padframe/ESD supply - inout vssio_pad, // Common padframe/ESD ground - inout vssio_pad2, // Common padframe/ESD ground - inout vccd_pad, // Common 1.8V supply - inout vssd_pad, // Common digital ground - inout vdda_pad, // Management analog 3.3V supply - inout vssa_pad, // Management analog ground - inout vdda1_pad, // User area 1 3.3V supply - inout vdda1_pad2, // User area 1 3.3V supply - inout vdda2_pad, // User area 2 3.3V supply - inout vssa1_pad, // User area 1 analog ground - inout vssa1_pad2, // User area 1 analog ground - inout vssa2_pad, // User area 2 analog ground - inout vccd1_pad, // User area 1 1.8V supply - inout vccd2_pad, // User area 2 1.8V supply - inout vssd1_pad, // User area 1 digital ground - inout vssd2_pad, // User area 2 digital ground - - // Core Side - inout vddio, // Common padframe/ESD supply - inout vssio, // Common padframe/ESD ground - inout vccd, // Common 1.8V supply - inout vssd, // Common digital ground - inout vdda, // Management analog 3.3V supply - inout vssa, // Management analog ground - inout vdda1, // User area 1 3.3V supply - inout vdda2, // User area 2 3.3V supply - inout vssa1, // User area 1 analog ground - inout vssa2, // User area 2 analog ground - inout vccd1, // User area 1 1.8V supply - inout vccd2, // User area 2 1.8V supply - inout vssd1, // User area 1 digital ground - inout vssd2, // User area 2 digital ground - - inout gpio, - input clock, - input resetb, - output flash_csb, - output flash_clk, - inout flash_io0, - inout flash_io1, - // Chip Core Interface - input porb_h, - input por, - output resetb_core_h, - output clock_core, - input gpio_out_core, - output gpio_in_core, - input gpio_mode0_core, - input gpio_mode1_core, - input gpio_outenb_core, - input gpio_inenb_core, - input flash_csb_core, - input flash_clk_core, - input flash_csb_oeb_core, - input flash_clk_oeb_core, - input flash_io0_oeb_core, - input flash_io1_oeb_core, - input flash_csb_ieb_core, - input flash_clk_ieb_core, - input flash_io0_ieb_core, - input flash_io1_ieb_core, - input flash_io0_do_core, - input flash_io1_do_core, - output flash_io0_di_core, - output flash_io1_di_core, - // User project IOs - // mprj_io is defined for all pads, both digital and analog - inout [`MPRJ_IO_PADS-1:0] mprj_io, - // The section below is for the digital pads only. - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_out, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_oeb, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_inp_dis, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_ib_mode_sel, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_vtrip_sel, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_slow_sel, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_holdover, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_analog_en, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_analog_sel, - input [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_analog_pol, - input [(`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2)*3-1:0] mprj_io_dm, - output [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_in, - output [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-1:0] mprj_io_in_3v3, - - // User project direct access to gpio pad connections for analog - // "analog" connects to the "esd_0" pin of the GPIO pad, and - // "analog_noesd" connects to the "noesd" pin of the GPIO pad. - - // User side 1: Connects to all but the first 7 pads; - // User side 2: Connects to all but the last 2 pads - inout [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-10:0] mprj_gpio_analog, - inout [`MPRJ_IO_PADS-ANALOG_PADS_1-ANALOG_PADS_2-10:0] mprj_gpio_noesd, - - // Core connections for the analog signals - inout [ANALOG_PADS_1+ANALOG_PADS_2-1:0] mprj_analog, - - // These are clamp connections for the clamps in the analog cells, if - // they are used for power supplies. - // User side 1: Connects to - input [2:0] mprj_clamp_high, - input [2:0] mprj_clamp_low -); - - wire analog_a, analog_b; - wire vddio_q, vssio_q; - - // To be considered: Master hold signal on all user pads (?) - // For now, set holdh_n to 1 (NOTE: This is in the 3.3V domain) - // and setting enh to porb_h. - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_hldh_n; - wire [`MPRJ_IO_PADS-`ANALOG_PADS-1:0] mprj_io_enh; - - assign mprj_io_hldh_n = {`MPRJ_IO_PADS{vddio}}; - assign mprj_io_enh = {`MPRJ_IO_PADS{porb_h}}; - - // Instantiate power and ground pads for management domain - // 12 pads: vddio, vssio, vdda, vssa, vccd, vssd - // One each HV and LV clamp. - - // HV clamps connect between one HV power rail and one ground - // LV clamps have two clamps connecting between any two LV power - // rails and grounds, and one back-to-back diode which connects - // between the first LV clamp ground and any other ground. - - sky130_ef_io__vddio_hvc_clamped_pad \mgmt_vddio_hvclamp_pad[0] ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDIO(vddio) -`else - ,.VDDIO_PAD(vddio_pad) -`endif - ); - - // lies in user area 2 - sky130_ef_io__vddio_hvc_clamped_pad \mgmt_vddio_hvclamp_pad[1] ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDIO(vddio) -`else - ,.VDDIO_PAD(vddio_pad2) -`endif - ); - - sky130_ef_io__vdda_hvc_clamped_pad mgmt_vdda_hvclamp_pad ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDA(vdda) -`else - ,.VDDA_PAD(vdda_pad) -`endif ); - - sky130_ef_io__vccd_lvc_clamped_pad mgmt_vccd_lvclamp_pad ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VCCD(vccd) -`else - ,.VCCD_PAD(vccd_pad) -`endif - ); - - sky130_ef_io__vssio_hvc_clamped_pad \mgmt_vssio_hvclamp_pad[0] ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSIO(vssio) -`else - ,.VSSIO_PAD(vssio_pad) -`endif - ); - - sky130_ef_io__vssio_hvc_clamped_pad \mgmt_vssio_hvclamp_pad[1] ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSIO(vssio) -`else - ,.VSSIO_PAD(vssio_pad2) -`endif - ); - - sky130_ef_io__vssa_hvc_clamped_pad mgmt_vssa_hvclamp_pad ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSA(vssa) -`else - ,.VSSA_PAD(vssa_pad) -`endif - ); - - sky130_ef_io__vssd_lvc_clamped_pad mgmt_vssd_lvclmap_pad ( - `MGMT_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSD(vssd) -`else - ,.VSSD_PAD(vssd_pad) -`endif - ); - - // Instantiate power and ground pads for user 1 domain - // 8 pads: vdda, vssa, vccd, vssd; One each HV and LV clamp. - - sky130_ef_io__vdda_hvc_clamped_pad \user1_vdda_hvclamp_pad[0] ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDA(vdda1) -`else - ,.VDDA_PAD(vdda1_pad) -`endif - ); - - sky130_ef_io__vdda_hvc_clamped_pad \user1_vdda_hvclamp_pad[1] ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDA(vdda1) -`else - ,.VDDA_PAD(vdda1_pad2) -`endif - ); - - sky130_ef_io__vccd_lvc_clamped2_pad user1_vccd_lvclamp_pad ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VCCD(vccd1) -`else - ,.VCCD_PAD(vccd1_pad) -`endif - ); - - sky130_ef_io__vssa_hvc_clamped_pad \user1_vssa_hvclamp_pad[0] ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSA(vssa1) -`else - ,.VSSA_PAD(vssa1_pad) -`endif - ); - - sky130_ef_io__vssa_hvc_clamped_pad \user1_vssa_hvclamp_pad[1] ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSA(vssa1) -`else - ,.VSSA_PAD(vssa1_pad2) -`endif - ); - - sky130_ef_io__vssd_lvc_clamped2_pad user1_vssd_lvclmap_pad ( - `USER1_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSD(vssd1) -`else - ,.VSSD_PAD(vssd1_pad) -`endif - ); - - // Instantiate power and ground pads for user 2 domain - // 8 pads: vdda, vssa, vccd, vssd; One each HV and LV clamp. - - sky130_ef_io__vdda_hvc_clamped_pad user2_vdda_hvclamp_pad ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VDDA(vdda2) -`else - ,.VDDA_PAD(vdda2_pad) -`endif - ); - - sky130_ef_io__vccd_lvc_clamped2_pad user2_vccd_lvclamp_pad ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VCCD(vccd2) -`else - ,.VCCD_PAD(vccd2_pad) -`endif - ); - - sky130_ef_io__vssa_hvc_clamped_pad user2_vssa_hvclamp_pad ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSA(vssa2) -`else - ,.VSSA_PAD(vssa2_pad) -`endif - ); - - sky130_ef_io__vssd_lvc_clamped2_pad user2_vssd_lvclmap_pad ( - `USER2_ABUTMENT_PINS -`ifdef TOP_ROUTING - .VSSD(vssd2) -`else - ,.VSSD_PAD(vssd2_pad) -`endif - ); - - // Instantiate analog pads in user area 1 using the custom analog pad - sky130_ef_io__analog_pad user1_analog_pad [ANALOG_PADS_1-2:0] ( - `USER1_ABUTMENT_PINS -`ifndef TOP_ROUTING - // .VDDIO(vddio) - ,.P_PAD(mprj_io[`MPRJ_IO_PADS_1-2:`MPRJ_IO_PADS_1-ANALOG_PADS_1]), -`endif - .P_CORE(mprj_analog[ANALOG_PADS_1-2:0]) - ); - - // Last analog pad is a power pad, to provide a clamp resource. - sky130_ef_io__top_power_hvc user1_analog_pad_with_clamp ( - `USER1_ABUTMENT_PINS -`ifndef TOP_ROUTING - // .VDDIO(vddio) - ,.P_PAD(mprj_io[`MPRJ_IO_PADS_1-1]), -`endif - `HVCLAMP_PINS(mprj_clamp_high[0], - mprj_clamp_low[0]), - .P_CORE(mprj_analog[ANALOG_PADS_1-1]) - ); - - // Instantiate analog pads in user area 2 using the custom analog pad. - sky130_ef_io__analog_pad user2_analog_pad [ANALOG_PADS_2-3:0] ( - `USER2_ABUTMENT_PINS -`ifndef TOP_ROUTING - // .VDDIO(vddio) - ,.P_PAD(mprj_io[`MPRJ_IO_PADS_1+ANALOG_PADS_2-1:`MPRJ_IO_PADS_1+2]), -`endif - .P_CORE(mprj_analog[ANALOG_PADS_2+ANALOG_PADS_1-1:ANALOG_PADS_1+2]) - ); - - // Last two analog pads are power pads, to provide clamp resources. - sky130_ef_io__top_power_hvc user2_analog_pad_with_clamp [1:0] ( - `USER2_ABUTMENT_PINS -`ifndef TOP_ROUTING - // .VDDIO(vddio) - ,.P_PAD(mprj_io[`MPRJ_IO_PADS_1+1:`MPRJ_IO_PADS_1]), -`endif - `HVCLAMP_PINS(mprj_clamp_high[2:1], mprj_clamp_low[2:1]), - .P_CORE(mprj_analog[`ANALOG_PADS_1+1:ANALOG_PADS_1]) - ); - - wire [2:0] dm_all = - {gpio_mode1_core, gpio_mode1_core, gpio_mode0_core}; - wire[2:0] flash_io0_mode = - {flash_io0_ieb_core, flash_io0_ieb_core, flash_io0_oeb_core}; - wire[2:0] flash_io1_mode = - {flash_io1_ieb_core, flash_io1_ieb_core, flash_io1_oeb_core}; - - // Management clock input pad - `INPUT_PAD(clock, clock_core); - - // Management GPIO pad - `INOUT_PAD( - gpio, gpio_in_core, gpio_out_core, - gpio_inenb_core, gpio_outenb_core, dm_all); - - // Management Flash SPI pads - `INOUT_PAD( - flash_io0, flash_io0_di_core, flash_io0_do_core, - flash_io0_ieb_core, flash_io0_oeb_core, flash_io0_mode); - `INOUT_PAD( - flash_io1, flash_io1_di_core, flash_io1_do_core, - flash_io1_ieb_core, flash_io1_oeb_core, flash_io1_mode); - - `OUTPUT_PAD(flash_csb, flash_csb_core, flash_csb_ieb_core, flash_csb_oeb_core); - `OUTPUT_PAD(flash_clk, flash_clk_core, flash_clk_ieb_core, flash_clk_oeb_core); - - // NOTE: The analog_out pad from the raven chip has been replaced by - // the digital reset input resetb on caravel due to the lack of an on-board - // power-on-reset circuit. The XRES pad is used for providing a glitch- - // free reset. - - wire xresloop; - sky130_fd_io__top_xres4v2 resetb_pad ( - `MGMT_ABUTMENT_PINS - `ifndef TOP_ROUTING - ,.PAD(resetb), - `endif - .TIE_WEAK_HI_H(xresloop), // Loop-back connection to pad through pad_a_esd_h - .TIE_HI_ESD(), - .TIE_LO_ESD(), - .PAD_A_ESD_H(xresloop), - .XRES_H_N(resetb_core_h), - .DISABLE_PULLUP_H(vssio), // 0 = enable pull-up on reset pad - .ENABLE_H(porb_h), // Power-on-reset - .EN_VDDIO_SIG_H(vssio), // No idea. - .INP_SEL_H(vssio), // 1 = use filt_in_h else filter the pad input - .FILT_IN_H(vssio), // Alternate input for glitch filter - .PULLUP_H(vssio), // Pullup connection for alternate filter input - .ENABLE_VDDIO(vccd) - ); - - // Corner cells (These are overlay cells; it is not clear what is normally - // supposed to go under them.) - - sky130_ef_io__corner_pad mgmt_corner [1:0] ( -`ifndef TOP_ROUTING - .VSSIO(vssio), - .VDDIO(vddio), - .VDDIO_Q(vddio_q), - .VSSIO_Q(vssio_q), - .AMUXBUS_A(analog_a), - .AMUXBUS_B(analog_b), - .VSSD(vssd), - .VSSA(vssa), - .VSWITCH(vddio), - .VDDA(vdda), - .VCCD(vccd), - .VCCHIB(vccd) -`else - .VCCHIB() -`endif - - ); - sky130_ef_io__corner_pad user1_corner ( -`ifndef TOP_ROUTING - .VSSIO(vssio), - .VDDIO(vddio), - .VDDIO_Q(vddio_q), - .VSSIO_Q(vssio_q), - .AMUXBUS_A(analog_a), - .AMUXBUS_B(analog_b), - .VSSD(vssd1), - .VSSA(vssa1), - .VSWITCH(vddio), - .VDDA(vdda1), - .VCCD(vccd1), - .VCCHIB(vccd) -`else - .VCCHIB() -`endif - ); - sky130_ef_io__corner_pad user2_corner ( -`ifndef TOP_ROUTING - .VSSIO(vssio), - .VDDIO(vddio), - .VDDIO_Q(vddio_q), - .VSSIO_Q(vssio_q), - .AMUXBUS_A(analog_a), - .AMUXBUS_B(analog_b), - .VSSD(vssd2), - .VSSA(vssa2), - .VSWITCH(vddio), - .VDDA(vdda2), - .VCCD(vccd2), - .VCCHIB(vccd) -`else - .VCCHIB() -`endif - ); - - mprj_io #( - .AREA1PADS(`MPRJ_IO_PADS_1 - ANALOG_PADS_1), - .TOTAL_PADS(`MPRJ_IO_PADS - ANALOG_PADS_1 - ANALOG_PADS_2) - ) mprj_pads ( - .vddio(vddio), - .vssio(vssio), - .vccd(vccd), - .vssd(vssd), - .vdda1(vdda1), - .vdda2(vdda2), - .vssa1(vssa1), - .vssa2(vssa2), - .vccd1(vccd1), - .vccd2(vccd2), - .vssd1(vssd1), - .vssd2(vssd2), - .vddio_q(vddio_q), - .vssio_q(vssio_q), - .analog_a(analog_a), - .analog_b(analog_b), - .porb_h(porb_h), - - .io({mprj_io[`MPRJ_IO_PADS-1:`MPRJ_IO_PADS_1+ANALOG_PADS_2], - mprj_io[`MPRJ_IO_PADS_1-ANALOG_PADS_1-1:0]}), - .io_out(mprj_io_out), - .oeb(mprj_io_oeb), - .hldh_n(mprj_io_hldh_n), - .enh(mprj_io_enh), - .inp_dis(mprj_io_inp_dis), - .ib_mode_sel(mprj_io_ib_mode_sel), - .vtrip_sel(mprj_io_vtrip_sel), - .holdover(mprj_io_holdover), - .slow_sel(mprj_io_slow_sel), - .analog_en(mprj_io_analog_en), - .analog_sel(mprj_io_analog_sel), - .analog_pol(mprj_io_analog_pol), - .dm(mprj_io_dm), - .io_in(mprj_io_in), - .io_in_3v3(mprj_io_in_3v3), - .analog_io(mprj_gpio_analog), - .analog_noesd_io(mprj_gpio_noesd) - ); - -endmodule -// `default_nettype wire
diff --git a/caravel/rtl/clock_div.v b/caravel/rtl/clock_div.v deleted file mode 100644 index 49ff44b..0000000 --- a/caravel/rtl/clock_div.v +++ /dev/null
@@ -1,213 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -/* Integer-N clock divider */ -`default_nettype none - -module clock_div #( - parameter SIZE = 3 // Number of bits for the divider value -) ( - in, out, N, resetb -); - input in; // input clock - input [SIZE-1:0] N; // the number to be divided by - input resetb; // asynchronous reset (sense negative) - output out; // divided output clock - - wire out_odd; // output of odd divider - wire out_even; // output of even divider - wire not_zero; // signal to find divide by 0 case - wire enable_even; // enable of even divider - wire enable_odd; // enable of odd divider - - reg [SIZE-1:0] syncN; // N synchronized to output clock - reg [SIZE-1:0] syncNp; // N synchronized to output clock - - assign not_zero = | syncN[SIZE-1:1]; - - assign out = (out_odd & syncN[0] & not_zero) | (out_even & !syncN[0]); - assign enable_odd = syncN[0] & not_zero; - assign enable_even = !syncN[0]; - - // Divider value synchronization (double-synchronized to avoid metastability) - always @(posedge out or negedge resetb) begin - if (resetb == 1'b0) begin - syncN <= `CLK_DIV; // Default to divide-by-2 on system reset - syncNp <= `CLK_DIV; // Default to divide-by-2 on system reset - end else begin - syncNp <= N; - syncN <= syncNp; - end - end - - // Even divider - even even_0(in, out_even, syncN, resetb, not_zero, enable_even); - // Odd divider - odd odd_0(in, out_odd, syncN, resetb, enable_odd); - -endmodule // clock_div - -/* Odd divider */ - -module odd #( - parameter SIZE = 3 -) ( - clk, out, N, resetb, enable -); - input clk; // slow clock - output out; // fast output clock - input [SIZE-1:0] N; // division factor - input resetb; // synchronous reset - input enable; // odd enable - - reg [SIZE-1:0] counter; // these 2 counters are used - reg [SIZE-1:0] counter2; // to non-overlapping signals - reg out_counter; // positive edge triggered counter - reg out_counter2; // negative edge triggered counter - reg rst_pulse; // pulse generated when vector N changes - reg [SIZE-1:0] old_N; // gets set to old N when N is changed - wire not_zero; // if !not_zero, we devide by 1 - - // xor to generate 50% duty, half-period waves of final output - assign out = out_counter2 ^ out_counter; - - // positive edge counter/divider - always @(posedge clk or negedge resetb) begin - if (resetb == 1'b0) begin - counter <= `CLK_DIV; - out_counter <= 1; - end else if (rst_pulse) begin - counter <= N; - out_counter <= 1; - end else if (enable) begin - if (counter == 1) begin - counter <= N; - out_counter <= ~out_counter; - end else begin - counter <= counter - 1'b1; - end - end - end - - reg [SIZE-1:0] initial_begin; // this is used to offset the negative edge counter - // wire [SIZE:0] interm_3; // from the positive edge counter in order to - // assign interm_3 = {1'b0,N} + 2'b11; // guarante 50% duty cycle. - localparam [SIZE:0] interm_3 = {1'b0,`CLK_DIV} + 2'b11; - - // Counter driven by negative edge of clock. - - always @(negedge clk or negedge resetb) begin - if (resetb == 1'b0) begin - // reset the counter at system reset - counter2 <= `CLK_DIV; - initial_begin <= interm_3[SIZE:1]; - out_counter2 <= 1; - end else if (rst_pulse) begin - // reset the counter at change of N. - counter2 <= N; - initial_begin <= interm_3[SIZE:1]; - out_counter2 <= 1; - end else if ((initial_begin <= 1) && enable) begin - - // Do normal logic after odd calibration. - // This is the same as the even counter. - if (counter2 == 1) begin - counter2 <= N; - out_counter2 <= ~out_counter2; - end else begin - counter2 <= counter2 - 1'b1; - end - end else if (enable) begin - initial_begin <= initial_begin - 1'b1; - end - end - - // - // reset pulse generator: - // __ __ __ __ _ - // clk: __/ \__/ \__/ \__/ \__/ - // _ __________________________ - // N: _X__________________________ - // _____ - // rst_pulse: __/ \___________________ - // - // This block generates an internal reset for the odd divider in the - // form of a single pulse signal when the odd divider is enabled. - - always @(posedge clk or negedge resetb) begin - if (resetb == 1'b0) begin - rst_pulse <= 0; - end else if (enable) begin - if (N != old_N) begin - // pulse when reset changes - rst_pulse <= 1; - end else begin - rst_pulse <= 0; - end - end - end - - always @(posedge clk) begin - // always save the old N value to guarante reset from - // an even-to-odd transition. - old_N <= N; - end - -endmodule // odd - -/* Even divider */ - -module even #( - parameter SIZE = 3 -) ( - clk, out, N, resetb, not_zero, enable -); - input clk; // fast input clock - output out; // slower divided clock - input [SIZE-1:0] N; // divide by factor 'N' - input resetb; // asynchronous reset - input not_zero; // if !not_zero divide by 1 - input enable; // enable the even divider - - reg [SIZE-1:0] counter; - reg out_counter; - wire [SIZE-1:0] div_2; - - // if N=0 just output the clock, otherwise, divide it. - assign out = (clk & !not_zero) | (out_counter & not_zero); - assign div_2 = {1'b0, N[SIZE-1:1]}; - - // simple flip-flop even divider - always @(posedge clk or negedge resetb) begin - if (resetb == 1'b0) begin - counter <= 1; - out_counter <= 1; - - end else if (enable) begin - // only use switching power if enabled - if (counter == 1) begin - // divide after counter has reached bottom - // of interval 'N' which will be value '1' - counter <= div_2; - out_counter <= ~out_counter; - end else begin - // decrement the counter and wait - counter <= counter-1; // to start next transition. - end - end - end - -endmodule //even -`default_nettype wire
diff --git a/caravel/rtl/convert_gpio_sigs.v b/caravel/rtl/convert_gpio_sigs.v deleted file mode 100644 index e9e8351..0000000 --- a/caravel/rtl/convert_gpio_sigs.v +++ /dev/null
@@ -1,51 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -/* Convert the standard set of GPIO signals: input, output, output_enb, - * pullup, and pulldown into the set needed by the s8 GPIO pads: - * input, output, output_enb, input_enb, mode. Note that dm[2] on - * thepads is always equal to dm[1] in this setup, so mode is shown as - * only a 2-bit signal. - * - * This module is bit-sliced. Instantiate once for each GPIO pad. - * (Caravel has only one GPIO pad, so bit-slicing is irrelevant.) - */ - -module convert_gpio_sigs ( - input gpio_out, - input gpio_outenb, - input gpio_pu, - input gpio_pd, - output gpio_out_pad, - output gpio_outenb_pad, - output gpio_inenb_pad, - output gpio_mode1_pad, - output gpio_mode0_pad -); - - assign gpio_out_pad = (gpio_pu == 1'b0 && gpio_pd == 1'b0) ? gpio_out : - (gpio_pu == 1'b1) ? 1 : 0; - - assign gpio_outenb_pad = (gpio_outenb == 1'b0) ? 0 : - (gpio_pu == 1'b1 || gpio_pd == 1'b1) ? 0 : 1; - - assign gpio_inenb_pad = ~gpio_outenb; - - assign gpio_mode1_pad = ~gpio_outenb_pad; - assign gpio_mode0_pad = gpio_outenb; - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/counter_timer_high.v b/caravel/rtl/counter_timer_high.v deleted file mode 100644 index e13172e..0000000 --- a/caravel/rtl/counter_timer_high.v +++ /dev/null
@@ -1,295 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -/* Simple 32-bit counter-timer for Caravel. */ - -/* Counter acts as high 32 bits of a 64-bit counter - * when chained with the other counter - */ - -module counter_timer_high_wb # ( - parameter BASE_ADR = 32'h2400_0000, - parameter CONFIG = 8'h00, - parameter VALUE = 8'h04, - parameter DATA = 8'h08 -) ( - input wb_clk_i, - input wb_rst_i, - input [31:0] wb_adr_i, - input [31:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input wb_cyc_i, - input wb_stb_i, - - output wb_ack_o, - output [31:0] wb_dat_o, - input enable_in, - input stop_in, - input strobe, - input is_offset, - output stop_out, - output enable_out, - output irq -); - wire [31:0] counter_timer_reg_cfg_do; - wire [31:0] counter_timer_reg_val_do; - wire [31:0] counter_timer_reg_dat_do; - - wire resetn = ~wb_rst_i; - wire valid = wb_stb_i && wb_cyc_i; - wire counter_timer_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG)); - wire counter_timer_reg_val_sel = valid && (wb_adr_i == (BASE_ADR | VALUE)); - wire counter_timer_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA)); - - wire reg_cfg_we = (counter_timer_reg_cfg_sel) ? - (wb_sel_i[0] & {wb_we_i}): 1'b0; - wire [3:0] reg_val_we = (counter_timer_reg_val_sel) ? - (wb_sel_i & {4{wb_we_i}}): 4'b0000; - wire [3:0] reg_dat_we = (counter_timer_reg_dat_sel) ? - (wb_sel_i & {4{wb_we_i}}): 4'b0000; - - wire [31:0] mem_wdata = wb_dat_i; - wire reg_dat_re = counter_timer_reg_dat_sel && !wb_sel_i && ~wb_we_i; - - assign wb_dat_o = (counter_timer_reg_cfg_sel) ? counter_timer_reg_cfg_do : - (counter_timer_reg_val_sel) ? counter_timer_reg_val_do : - counter_timer_reg_dat_do; - assign wb_ack_o = counter_timer_reg_cfg_sel || counter_timer_reg_val_sel || - counter_timer_reg_dat_sel; - - counter_timer_high counter_timer_high_inst ( - .resetn(resetn), - .clkin(wb_clk_i), - .reg_val_we(reg_val_we), - .reg_val_di(mem_wdata), - .reg_val_do(counter_timer_reg_val_do), - .reg_cfg_we(reg_cfg_we), - .reg_cfg_di(mem_wdata), - .reg_cfg_do(counter_timer_reg_cfg_do), - .reg_dat_we(reg_dat_we), - .reg_dat_di(mem_wdata), - .reg_dat_do(counter_timer_reg_dat_do), - .enable_in(enable_in), - .stop_in(stop_in), - .is_offset(is_offset), - .stop_out(stop_out), - .strobe(strobe), - .enable_out(enable_out), - .irq_out(irq) - ); - -endmodule - -module counter_timer_high ( - input resetn, - input clkin, - - input [3:0] reg_val_we, - input [31:0] reg_val_di, - output [31:0] reg_val_do, - - input reg_cfg_we, - input [31:0] reg_cfg_di, - output [31:0] reg_cfg_do, - - input [3:0] reg_dat_we, - input [31:0] reg_dat_di, - output [31:0] reg_dat_do, - input stop_in, - input enable_in, - input is_offset, - input strobe, - output stop_out, - output enable_out, - output irq_out -); - -reg [31:0] value_cur; -reg [31:0] value_reset; -reg irq_out; -wire enable_in; // Enable from chained counter -wire strobe; // Count strobe from low word counter -wire enable_out; // Enable to chained counter (sync) -reg stop_out; // Stop signal to low word counter - -wire [31:0] value_cur_plus; // Next value, on up-count -wire [31:0] value_cur_minus; // Next value, on down-count -wire [31:0] value_check_plus; // Value to check for stop condition during up count -wire loc_enable; // Local enable - -reg enable; // Enable (start) the counter/timer -reg lastenable; // Previous state of enable (catch rising/falling edge) -reg oneshot; // Set oneshot (1) mode or continuous (0) mode -reg updown; // Count up (1) or down (0) -reg irq_ena; // Enable interrupt on timeout -reg chain; // Chain to a secondary timer - -// Configuration register - -assign reg_cfg_do = {27'd0, irq_ena, chain, updown, oneshot, enable}; - -always @(posedge clkin or negedge resetn) begin - if (resetn == 1'b0) begin - enable <= 1'b0; - oneshot <= 1'b0; - updown <= 1'b0; - chain <= 1'b0; - irq_ena <= 1'b0; - end else begin - if (reg_cfg_we) begin - enable <= reg_cfg_di[0]; - oneshot <= reg_cfg_di[1]; - updown <= reg_cfg_di[2]; - chain <= reg_cfg_di[3]; - irq_ena <= reg_cfg_di[4]; - end - end -end - -// Counter/timer reset value register - -assign reg_val_do = value_reset; - -always @(posedge clkin or negedge resetn) begin - if (resetn == 1'b0) begin - value_reset <= 32'd0; - end else begin - if (reg_val_we[3]) value_reset[31:24] <= reg_val_di[31:24]; - if (reg_val_we[2]) value_reset[23:16] <= reg_val_di[23:16]; - if (reg_val_we[1]) value_reset[15:8] <= reg_val_di[15:8]; - if (reg_val_we[0]) value_reset[7:0] <= reg_val_di[7:0]; - end -end - -assign reg_dat_do = value_cur; - -// Counter/timer current value register and timer implementation - -assign value_cur_plus = value_cur + 1; -assign value_cur_minus = value_cur - 1; - -assign value_check_plus = (is_offset) ? value_cur_plus : value_cur; - -assign enable_out = enable; -assign loc_enable = (chain == 1'b1) ? (enable && enable_in) : enable; - -// When acting as the high 32 bit word of a 64-bit chained counter: -// -// It counts when the low 32-bit counter strobes (strobe == 1). -// It sets "stop_out" and stops on the stop condition. - -always @(posedge clkin or negedge resetn) begin - if (resetn == 1'b0) begin - value_cur <= 32'd0; - stop_out <= 1'b0; - irq_out <= 1'b0; - lastenable <= 1'b0; - end else begin - lastenable <= loc_enable; - - if (reg_dat_we != 4'b0000) begin - if (reg_dat_we[3] == 1'b1) value_cur[31:24] <= reg_dat_di[31:24]; - if (reg_dat_we[2] == 1'b1) value_cur[23:16] <= reg_dat_di[23:16]; - if (reg_dat_we[1] == 1'b1) value_cur[15:8] <= reg_dat_di[15:8]; - if (reg_dat_we[0] == 1'b1) value_cur[7:0] <= reg_dat_di[7:0]; - - end else if (loc_enable == 1'b1) begin - /* IRQ signals one cycle after stop, if IRQ is enabled */ - /* IRQ lasts for one cycle only. */ - irq_out <= (irq_ena) ? (stop_out & ~irq_out) : 1'b0; - - if (updown == 1'b1) begin - if (lastenable == 1'b0) begin - value_cur <= 32'd0; - stop_out <= 1'b0; - end else if (chain) begin - // Chained counter behavior - if (value_check_plus == value_reset) begin - stop_out <= 1'b1; - end - if (stop_in == 1'b1) begin // lower word counter stopped - if (oneshot != 1'b1) begin - value_cur <= 32'd0; // reset count - stop_out <= 1'b0; // no longer stopped - end else if (strobe == 1'b1) begin - value_cur <= value_cur_plus; - end - end else if (strobe == 1'b1) begin - value_cur <= value_cur_plus; - end - end else begin - // Standalone counter behavior - if (value_cur == value_reset) begin - if (oneshot != 1'b1) begin - value_cur <= 32'd0; - stop_out <= 1'b0; - end else begin - stop_out <= 1'b1; - end - end else begin - if (value_cur_plus == 32'd0) begin - stop_out <= 1'b1; - end else begin - stop_out <= 1'b0; - end - value_cur <= value_cur_plus; // count up - end - end - end else begin - if (lastenable == 1'b0) begin - value_cur <= value_reset; - stop_out <= 1'b0; - end else if (chain) begin - // Chained counter behavior - if (value_cur == 32'd0) begin - stop_out <= 1'b1; - end - if (stop_in == 1'b1) begin // lower word counter stopped - if (oneshot != 1'b1) begin - value_cur <= value_reset; // reset count - stop_out <= 1'b0; // no longer stopped - end - end else if (strobe == 1'b1) begin - value_cur <= value_cur_minus; // count down - end - end else begin - // Standalone counter behavior - if (value_cur == 32'd0) begin - if (oneshot != 1'b1) begin - value_cur <= value_reset; - stop_out <= 1'b0; - end else begin - stop_out <= 1'b1; - end - end else begin - if (value_cur_minus == 32'd0) begin - stop_out <= 1'b1; - end else begin - stop_out <= 1'b0; - end - value_cur <= value_cur_minus; // count down - end - end - end - end else begin - stop_out <= 1'b0; - end - end -end - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/counter_timer_low.v b/caravel/rtl/counter_timer_low.v deleted file mode 100644 index 06ed5d1..0000000 --- a/caravel/rtl/counter_timer_low.v +++ /dev/null
@@ -1,327 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -/* Simple 32-bit counter-timer for Caravel. */ - -/* Counter acts as low 32 bits of a 64-bit counter - * when chained with the other counter. - */ - -module counter_timer_low_wb # ( - parameter BASE_ADR = 32'h2400_0000, - parameter CONFIG = 8'h00, - parameter VALUE = 8'h04, - parameter DATA = 8'h08 -) ( - input wb_clk_i, - input wb_rst_i, - input [31:0] wb_adr_i, - input [31:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input wb_cyc_i, - input wb_stb_i, - - output wb_ack_o, - output [31:0] wb_dat_o, - - input stop_in, - input enable_in, - output strobe, - output is_offset, - output stop_out, - output enable_out, - output irq -); - wire [31:0] counter_timer_reg_cfg_do; - wire [31:0] counter_timer_reg_val_do; - wire [31:0] counter_timer_reg_dat_do; - - wire resetn = ~wb_rst_i; - wire valid = wb_stb_i && wb_cyc_i; - wire counter_timer_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG)); - wire counter_timer_reg_val_sel = valid && (wb_adr_i == (BASE_ADR | VALUE)); - wire counter_timer_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA)); - - wire reg_cfg_we = (counter_timer_reg_cfg_sel) ? - (wb_sel_i[0] & {wb_we_i}): 1'b0; - wire [3:0] reg_val_we = (counter_timer_reg_val_sel) ? - (wb_sel_i & {4{wb_we_i}}): 4'b0000; - wire [3:0] reg_dat_we = (counter_timer_reg_dat_sel) ? - (wb_sel_i & {4{wb_we_i}}): 4'b0000; - - wire [31:0] mem_wdata = wb_dat_i; - wire reg_dat_re = counter_timer_reg_dat_sel && !wb_sel_i && ~wb_we_i; - - assign wb_dat_o = (counter_timer_reg_cfg_sel) ? counter_timer_reg_cfg_do : - (counter_timer_reg_val_sel) ? counter_timer_reg_val_do : - counter_timer_reg_dat_do; - assign wb_ack_o = counter_timer_reg_cfg_sel || counter_timer_reg_val_sel || - counter_timer_reg_dat_sel; - - counter_timer_low counter_timer_low_inst ( - .resetn(resetn), - .clkin(wb_clk_i), - .reg_val_we(reg_val_we), - .reg_val_di(mem_wdata), - .reg_val_do(counter_timer_reg_val_do), - .reg_cfg_we(reg_cfg_we), - .reg_cfg_di(mem_wdata), - .reg_cfg_do(counter_timer_reg_cfg_do), - .reg_dat_we(reg_dat_we), - .reg_dat_di(mem_wdata), - .reg_dat_do(counter_timer_reg_dat_do), - .stop_in(stop_in), - .strobe(strobe), - .is_offset(is_offset), - .enable_in(enable_in), - .stop_out(stop_out), - .enable_out(enable_out), - .irq_out(irq) - ); - -endmodule - -module counter_timer_low ( - input resetn, - input clkin, - - input [3:0] reg_val_we, - input [31:0] reg_val_di, - output [31:0] reg_val_do, - - input reg_cfg_we, - input [31:0] reg_cfg_di, - output [31:0] reg_cfg_do, - - input [3:0] reg_dat_we, - input [31:0] reg_dat_di, - output [31:0] reg_dat_do, - - input stop_in, - input enable_in, - output strobe, - output enable_out, - output stop_out, - output is_offset, - output irq_out -); - -reg [31:0] value_cur; -reg [31:0] value_reset; -reg irq_out; -wire stop_in; // High 32 bits counter has stopped -reg strobe; // Strobe to high 32 bits counter; occurs - // one cycle before actual timeout and - // irq signal. -reg stop_out; // Stop condition flag - -wire [31:0] value_cur_plus; // Next value, on up-count -wire [31:0] value_cur_minus; // Next value, on down-count -wire is_offset; -wire loc_enable; - -reg enable; // Enable (start) the counter/timer -reg lastenable; // Previous state of enable (catch rising/falling edge) -reg oneshot; // Set oneshot (1) mode or continuous (0) mode -reg updown; // Count up (1) or down (0) -reg irq_ena; // Enable interrupt on timeout -reg chain; // Chain to a secondary timer - -// Configuration register - -assign reg_cfg_do = {27'd0, irq_ena, chain, updown, oneshot, enable}; - -always @(posedge clkin or negedge resetn) begin - if (resetn == 1'b0) begin - enable <= 1'b0; - oneshot <= 1'b0; - updown <= 1'b0; - chain <= 1'b0; - irq_ena <= 1'b0; - end else begin - if (reg_cfg_we) begin - enable <= reg_cfg_di[0]; - oneshot <= reg_cfg_di[1]; - updown <= reg_cfg_di[2]; - chain <= reg_cfg_di[3]; - irq_ena <= reg_cfg_di[4]; - end - end -end - -// Counter/timer reset value register - -assign reg_val_do = value_reset; - -always @(posedge clkin or negedge resetn) begin - if (resetn == 1'b0) begin - value_reset <= 32'd0; - end else begin - if (reg_val_we[3]) value_reset[31:24] <= reg_val_di[31:24]; - if (reg_val_we[2]) value_reset[23:16] <= reg_val_di[23:16]; - if (reg_val_we[1]) value_reset[15:8] <= reg_val_di[15:8]; - if (reg_val_we[0]) value_reset[7:0] <= reg_val_di[7:0]; - end -end - -assign reg_dat_do = value_cur; - -// Counter/timer current value register and timer implementation - -assign value_cur_plus = value_cur + 1; -assign value_cur_minus = value_cur - 1; - -assign loc_enable = (chain == 1'b1) ? (enable && enable_in) : enable; -assign enable_out = enable; - -// If counting up and the stop condition on the low 32 bits is zero, -// then signal to the high word counter that the stop condition of the -// high word must be adjusted by one, since it will roll over at the same -// time and must be signaled early. - -assign is_offset = ((updown == 1'b1) && (value_reset == 0)); - -// When acting as low 32-bit word of a 64-bit chained counter: -// It sets the output strobe on the stop condition, one cycle early. -// It stops on the stop condition if "stop_in" is high. - -always @(posedge clkin or negedge resetn) begin - if (resetn == 1'b0) begin - value_cur <= 32'd0; - strobe <= 1'b0; - stop_out <= 1'b0; - irq_out <= 1'b0; - lastenable <= 1'b0; - end else begin - lastenable <= loc_enable; - - if (reg_dat_we != 4'b0000) begin - if (reg_dat_we[3] == 1'b1) value_cur[31:24] <= reg_dat_di[31:24]; - if (reg_dat_we[2] == 1'b1) value_cur[23:16] <= reg_dat_di[23:16]; - if (reg_dat_we[1] == 1'b1) value_cur[15:8] <= reg_dat_di[15:8]; - if (reg_dat_we[0] == 1'b1) value_cur[7:0] <= reg_dat_di[7:0]; - - end else if (loc_enable == 1'b1) begin - /* IRQ signals one cycle after stop_out, if IRQ is enabled */ - /* IRQ lasts for one clock cycle only. */ - irq_out <= (irq_ena) ? (stop_out & ~irq_out) : 1'b0; - - if (updown == 1'b1) begin - if (lastenable == 1'b0) begin - value_cur <= 32'd0; - strobe <= 1'b0; - stop_out <= 1'b0; - end else if (chain == 1'b1) begin - // Rollover strobe (2 clock cycles advanced) - if (value_cur == -1) begin - strobe <= 1'b1; - end else begin - strobe <= 1'b0; - end - - // Chained counter behavior - if ((stop_in == 1'b1) && (value_cur == value_reset)) begin - if (oneshot != 1'b1) begin - value_cur <= 32'd0; - stop_out <= 1'b0; - end else begin - stop_out <= 1'b1; - end - end else begin - if ((stop_in == 1'b1) && (value_cur_plus == value_reset)) begin - stop_out <= 1'b1; - end else begin - stop_out <= 1'b0; - end - value_cur <= value_cur_plus; // count up - end - end else begin - - // Single 32-bit counter behavior - if (value_cur == value_reset) begin - if (oneshot != 1'b1) begin - value_cur <= 32'd0; - stop_out <= 1'b0; - end else begin - stop_out <= 1'b1; - end - end else begin - if (value_cur_plus == value_reset) begin - stop_out <= 1'b1; - end else begin - stop_out <= 1'b0; - end - value_cur <= value_cur_plus; // count up - end - end - end else begin - if (lastenable == 1'b0) begin - value_cur <= value_reset; - stop_out <= 1'b0; - strobe <= 1'b0; - end else if (chain == 1'b1) begin - // Rollover strobe (2 clock cycles advanced) - if (value_cur == 2) begin - strobe <= 1'b1; - end else begin - strobe <= 1'b0; - end - - // Chained counter behavior - if ((stop_in == 1'b1) && (value_cur == 32'd0)) begin - if (oneshot != 1'b1) begin - value_cur <= value_reset; - stop_out <= 1'b0; - end else begin - stop_out <= 1'b1; - end - end else begin - if ((stop_in == 1'b1) && (value_cur_minus == 32'd0)) begin - stop_out <= 1'b1; - end else begin - stop_out <= 1'b0; - end - value_cur <= value_cur_minus; // count down - end - end else begin - - // Single 32-bit counter behavior - if (value_cur == 32'd0) begin - if (oneshot != 1'b1) begin - value_cur <= value_reset; - stop_out <= 1'b0; - end else begin - stop_out <= 1'b1; - end - end else begin - if (value_cur_minus == 32'd0) begin - stop_out <= 1'b1; - end else begin - stop_out <= 1'b0; - end - value_cur <= value_cur_minus; // count down - end - end - end - end else begin - strobe <= 1'b0; - end - end -end - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/defines.v b/caravel/rtl/defines.v deleted file mode 100644 index 9c3120c..0000000 --- a/caravel/rtl/defines.v +++ /dev/null
@@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none - -`ifndef __GLOBAL_DEFINE_H -// Global parameters -`define __GLOBAL_DEFINE_H - -`define MPRJ_IO_PADS_1 19 /* number of user GPIO pads on user1 side */ -`define MPRJ_IO_PADS_2 19 /* number of user GPIO pads on user2 side */ -`define MPRJ_IO_PADS (`MPRJ_IO_PADS_1 + `MPRJ_IO_PADS_2) - -`define MPRJ_PWR_PADS_1 2 /* vdda1, vccd1 enable/disable control */ -`define MPRJ_PWR_PADS_2 2 /* vdda2, vccd2 enable/disable control */ -`define MPRJ_PWR_PADS (`MPRJ_PWR_PADS_1 + `MPRJ_PWR_PADS_2) - -// Analog pads are only used by the "caravan" module and associated -// modules such as user_analog_project_wrapper and chip_io_alt. - -`define ANALOG_PADS_1 5 -`define ANALOG_PADS_2 6 - -`define ANALOG_PADS (`ANALOG_PADS_1 + `ANALOG_PADS_2) - -// Size of soc_mem_synth - -// Type and size of soc_mem -// `define USE_OPENRAM -`define USE_CUSTOM_DFFRAM -// don't change the following without double checking addr widths -`define MEM_WORDS 256 - -// Number of columns in the custom memory; takes one of three values: -// 1 column : 1 KB, 2 column: 2 KB, 4 column: 4KB -`define DFFRAM_WSIZE 4 -`define DFFRAM_USE_LATCH 0 - -// not really parameterized but just to easily keep track of the number -// of ram_block across different modules -`define RAM_BLOCKS 2 - -// Clock divisor default value -`define CLK_DIV 3'b010 - -// GPIO conrol default mode and enable -`define DM_INIT 3'b110 -`define OENB_INIT 1'b1 - -`endif // __GLOBAL_DEFINE_H
diff --git a/caravel/rtl/digital_pll.v b/caravel/rtl/digital_pll.v deleted file mode 100644 index b8dd69e..0000000 --- a/caravel/rtl/digital_pll.v +++ /dev/null
@@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -// Digital PLL (ring oscillator + controller) -// Technically this is a frequency locked loop, not a phase locked loop. - -`include "digital_pll_controller.v" -`include "ring_osc2x13.v" - -module digital_pll( -`ifdef USE_POWER_PINS - VPWR, - VGND, -`endif - resetb, enable, osc, clockp, div, dco, ext_trim); - -`ifdef USE_POWER_PINS - input VPWR; - input VGND; -`endif - - input resetb; // Sense negative reset - input enable; // Enable PLL - input osc; // Input oscillator to match - input [4:0] div; // PLL feedback division ratio - input dco; // Run in DCO mode - input [25:0] ext_trim; // External trim for DCO mode - - output [1:0] clockp; // Two 90 degree clock phases - - wire [25:0] itrim; // Internally generated trim bits - wire [25:0] otrim; // Trim bits applied to the ring oscillator - wire creset; // Controller reset - wire ireset; // Internal reset (external reset OR disable) - - assign ireset = ~resetb | ~enable; - - // In DCO mode: Hold controller in reset and apply external trim value - - assign itrim = (dco == 1'b0) ? otrim : ext_trim; - assign creset = (dco == 1'b0) ? ireset : 1'b1; - - ring_osc2x13 ringosc ( - .reset(ireset), - .trim(itrim), - .clockp(clockp) - ); - - digital_pll_controller pll_control ( - .reset(creset), - .clock(clockp[0]), - .osc(osc), - .div(div), - .trim(otrim) - ); - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/digital_pll_controller.v b/caravel/rtl/digital_pll_controller.v deleted file mode 100644 index ae13d9d..0000000 --- a/caravel/rtl/digital_pll_controller.v +++ /dev/null
@@ -1,136 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -// (True) digital PLL -// -// Output goes to a trimmable ring oscillator (see documentation). -// Ring oscillator should be trimmable to above and below maximum -// ranges of the input. -// -// Input "osc" comes from a fixed clock source (e.g., crystal oscillator -// output). -// -// Input "div" is the target number of clock cycles per oscillator cycle. -// e.g., if div == 8 then this is an 8X PLL. -// -// Clock "clock" is the PLL output being trimmed. -// (NOTE: To be done: Pass-through enable) -// -// Algorithm: -// -// 1) Trim is done by thermometer code. Reset to the highest value -// in case the fastest rate clock is too fast for the logic. -// -// 2) Count the number of contiguous 1s and 0s in "osc" -// periods of the master clock. If the count maxes out, it does -// not roll over. -// -// 3) Add the two counts together. -// -// 4) If the sum is less than div, then the clock is too slow, so -// decrease the trim code. If the sum is greater than div, the -// clock is too fast, so increase the trim code. If the sum -// is equal to div, the the trim code does not change. -// - -module digital_pll_controller(reset, clock, osc, div, trim); - input reset; - input clock; - input osc; - input [4:0] div; - output [25:0] trim; // Use ring_osc2x13, with 26 trim bits - - wire [25:0] trim; - reg [2:0] oscbuf; - reg [2:0] prep; - - reg [4:0] count0; - reg [4:0] count1; - reg [6:0] tval; // Includes 2 bits fractional - wire [4:0] tint; // Integer part of the above - - wire [5:0] sum; - - assign sum = count0 + count1; - - // Integer to thermometer code (maybe there's an algorithmic way?) - assign tint = tval[6:2]; - // |<--second-->|<-- first-->| - assign trim = (tint == 5'd0) ? 26'b0000000000000_0000000000000 : - (tint == 5'd1) ? 26'b0000000000000_0000000000001 : - (tint == 5'd2) ? 26'b0000000000000_0000001000001 : - (tint == 5'd3) ? 26'b0000000000000_0010001000001 : - (tint == 5'd4) ? 26'b0000000000000_0010001001001 : - (tint == 5'd5) ? 26'b0000000000000_0010101001001 : - (tint == 5'd6) ? 26'b0000000000000_1010101001001 : - (tint == 5'd7) ? 26'b0000000000000_1010101101001 : - (tint == 5'd8) ? 26'b0000000000000_1010101101101 : - (tint == 5'd9) ? 26'b0000000000000_1011101101101 : - (tint == 5'd10) ? 26'b0000000000000_1011101111101 : - (tint == 5'd11) ? 26'b0000000000000_1111101111101 : - (tint == 5'd12) ? 26'b0000000000000_1111101111111 : - (tint == 5'd13) ? 26'b0000000000000_1111111111111 : - (tint == 5'd14) ? 26'b0000000000001_1111111111111 : - (tint == 5'd15) ? 26'b0000001000001_1111111111111 : - (tint == 5'd16) ? 26'b0010001000001_1111111111111 : - (tint == 5'd17) ? 26'b0010001001001_1111111111111 : - (tint == 5'd18) ? 26'b0010101001001_1111111111111 : - (tint == 5'd19) ? 26'b1010101001001_1111111111111 : - (tint == 5'd20) ? 26'b1010101101001_1111111111111 : - (tint == 5'd21) ? 26'b1010101101101_1111111111111 : - (tint == 5'd22) ? 26'b1011101101101_1111111111111 : - (tint == 5'd23) ? 26'b1011101111101_1111111111111 : - (tint == 5'd24) ? 26'b1111101111101_1111111111111 : - (tint == 5'd25) ? 26'b1111101111111_1111111111111 : - 26'b1111111111111_1111111111111; - - always @(posedge clock or posedge reset) begin - if (reset == 1'b1) begin - tval <= 7'd0; // Note: trim[0] must be zero for startup to work. - oscbuf <= 3'd0; - prep <= 3'd0; - count0 <= 5'd0; - count1 <= 5'd0; - - end else begin - oscbuf <= {oscbuf[1:0], osc}; - - if (oscbuf[2] != oscbuf[1]) begin - count1 <= count0; - count0 <= 5'b00001; - prep <= {prep[1:0], 1'b1}; - - if (prep == 3'b111) begin - if (sum > div) begin - if (tval < 127) begin - tval <= tval + 1; - end - end else if (sum < div) begin - if (tval > 0) begin - tval <= tval - 1; - end - end - end - end else begin - if (count0 != 5'b11111) begin - count0 <= count0 + 1; - end - end - end - end - -endmodule // digital_pll_controller -`default_nettype wire
diff --git a/caravel/rtl/gpio_control_block.v b/caravel/rtl/gpio_control_block.v deleted file mode 100644 index 48f3979..0000000 --- a/caravel/rtl/gpio_control_block.v +++ /dev/null
@@ -1,278 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -/* - *--------------------------------------------------------------------- - * See gpio_control_block for description. This module is like - * gpio_contro_block except that it has an additional two management- - * Soc-facing pins, which are the out_enb line and the output line. - * If the chip is configured for output with the oeb control - * register = 1, then the oeb line is controlled by the additional - * signal from the management SoC. If the oeb control register = 0, - * then the output is disabled completely. The "io" line is input - * only in this module. - * - *--------------------------------------------------------------------- - */ - -/* - *--------------------------------------------------------------------- - * - * This module instantiates a shift register chain that passes through - * each gpio cell. These are connected end-to-end around the padframe - * periphery. The purpose is to avoid a massive number of control - * wires between the digital core and I/O, passing through the user area. - * - * See mprj_ctrl.v for the module that registers the data for each - * I/O and drives the input to the shift register. - * - *--------------------------------------------------------------------- - */ - -module gpio_control_block #( - parameter PAD_CTRL_BITS = 13, - // Parameterized initial startup state of the pad. - // The default parameters if unspecified is for the pad to be - // an input with no pull-up or pull-down, so that it is disconnected - // from the outside world. - parameter HOLD_INIT = 1'b0, - parameter SLOW_INIT = 1'b0, - parameter TRIP_INIT = 1'b0, - parameter IB_INIT = 1'b0, - parameter IENB_INIT = 1'b0, - parameter OENB_INIT = `OENB_INIT, - parameter DM_INIT = `DM_INIT, - parameter AENA_INIT = 1'b0, - parameter ASEL_INIT = 1'b0, - parameter APOL_INIT = 1'b0 -) ( - `ifdef USE_POWER_PINS - inout vccd, - inout vssd, - inout vccd1, - inout vssd1, - `endif - - // Management Soc-facing signals - input resetn, // Global reset, locally propagated - output resetn_out, - input serial_clock, // Global clock, locally propatated - output serial_clock_out, - - output mgmt_gpio_in, // Management from pad (input only) - input mgmt_gpio_out, // Management to pad (output only) - input mgmt_gpio_oeb, // Management to pad (output only) - - // Serial data chain for pad configuration - input serial_data_in, - output serial_data_out, - - // User-facing signals - input user_gpio_out, // User space to pad - input user_gpio_oeb, // Output enable (user) - output user_gpio_in, // Pad to user space - - // Pad-facing signals (Pad GPIOv2) - output pad_gpio_holdover, - output pad_gpio_slow_sel, - output pad_gpio_vtrip_sel, - output pad_gpio_inenb, - output pad_gpio_ib_mode_sel, - output pad_gpio_ana_en, - output pad_gpio_ana_sel, - output pad_gpio_ana_pol, - output [2:0] pad_gpio_dm, - output pad_gpio_outenb, - output pad_gpio_out, - input pad_gpio_in, - - // to provide a way to automatically disable/enable output - // from the outside with needing a conb cell - output one, - output zero -); - - /* Parameters defining the bit offset of each function in the chain */ - localparam MGMT_EN = 0; - localparam OEB = 1; - localparam HLDH = 2; - localparam INP_DIS = 3; - localparam MOD_SEL = 4; - localparam AN_EN = 5; - localparam AN_SEL = 6; - localparam AN_POL = 7; - localparam SLOW = 8; - localparam TRIP = 9; - localparam DM = 10; - - /* Internally registered signals */ - reg mgmt_ena; // Enable management SoC to access pad - reg gpio_holdover; - reg gpio_slow_sel; - reg gpio_vtrip_sel; - reg gpio_inenb; - reg gpio_ib_mode_sel; - reg gpio_outenb; - reg [2:0] gpio_dm; - reg gpio_ana_en; - reg gpio_ana_sel; - reg gpio_ana_pol; - - /* Derived output values */ - wire pad_gpio_holdover; - wire pad_gpio_slow_sel; - wire pad_gpio_vtrip_sel; - wire pad_gpio_inenb; - wire pad_gpio_ib_mode_sel; - wire pad_gpio_ana_en; - wire pad_gpio_ana_sel; - wire pad_gpio_ana_pol; - wire [2:0] pad_gpio_dm; - wire pad_gpio_outenb; - wire pad_gpio_out; - wire pad_gpio_in; - wire one; - wire zero; - - wire user_gpio_in; - wire gpio_in_unbuf; - wire gpio_logic1; - - /* Serial shift for the above (latched) values */ - reg [PAD_CTRL_BITS-1:0] shift_register; - - /* Utilize reset and clock to encode a load operation */ - wire load_data; - wire int_reset; - - /* Create internal reset and load signals from input reset and clock */ - assign serial_data_out = shift_register[PAD_CTRL_BITS-1]; - assign int_reset = (~resetn) & (~serial_clock); - assign load_data = (~resetn) & serial_clock; - - /* Propagate the clock and reset signals so that they aren't wired */ - /* all over the chip, but are just wired between the blocks. */ - assign serial_clock_out = serial_clock; - assign resetn_out = resetn; - - always @(posedge serial_clock or posedge int_reset) begin - if (int_reset == 1'b1) begin - /* Clear shift register */ - shift_register <= 'd0; - end else begin - /* Shift data in */ - shift_register <= {shift_register[PAD_CTRL_BITS-2:0], serial_data_in}; - end - end - - always @(posedge load_data or posedge int_reset) begin - if (int_reset == 1'b1) begin - /* Initial state on reset: Pad set to management input */ - mgmt_ena <= 1'b1; // Management SoC has control over all I/O - gpio_holdover <= HOLD_INIT; // All signals latched in hold mode - gpio_slow_sel <= SLOW_INIT; // Fast slew rate - gpio_vtrip_sel <= TRIP_INIT; // CMOS mode - gpio_ib_mode_sel <= IB_INIT; // CMOS mode - gpio_inenb <= IENB_INIT; // Input enabled - gpio_outenb <= OENB_INIT; // (unused placeholder) - gpio_dm <= DM_INIT; // Configured as input only - gpio_ana_en <= AENA_INIT; // Digital enabled - gpio_ana_sel <= ASEL_INIT; // Don't-care when gpio_ana_en = 0 - gpio_ana_pol <= APOL_INIT; // Don't-care when gpio_ana_en = 0 - end else begin - /* Load data */ - mgmt_ena <= shift_register[MGMT_EN]; - gpio_outenb <= shift_register[OEB]; - gpio_holdover <= shift_register[HLDH]; - gpio_inenb <= shift_register[INP_DIS]; - gpio_ib_mode_sel <= shift_register[MOD_SEL]; - gpio_ana_en <= shift_register[AN_EN]; - gpio_ana_sel <= shift_register[AN_SEL]; - gpio_ana_pol <= shift_register[AN_POL]; - gpio_slow_sel <= shift_register[SLOW]; - gpio_vtrip_sel <= shift_register[TRIP]; - gpio_dm <= shift_register[DM+2:DM]; - - end - end - - /* These pad configuration signals are static and do not change */ - /* after setup. */ - - assign pad_gpio_holdover = gpio_holdover; - assign pad_gpio_slow_sel = gpio_slow_sel; - assign pad_gpio_vtrip_sel = gpio_vtrip_sel; - assign pad_gpio_ib_mode_sel = gpio_ib_mode_sel; - assign pad_gpio_ana_en = gpio_ana_en; - assign pad_gpio_ana_sel = gpio_ana_sel; - assign pad_gpio_ana_pol = gpio_ana_pol; - assign pad_gpio_dm = gpio_dm; - assign pad_gpio_inenb = gpio_inenb; - - /* Implement pad control behavior depending on state of mgmt_ena */ - -// assign gpio_in_unbuf = (mgmt_ena) ? 1'b0 : pad_gpio_in; -// assign mgmt_gpio_in = (mgmt_ena) ? ((gpio_inenb == 1'b0) ? -// pad_gpio_in : 1'bz) : 1'b0; - - assign gpio_in_unbuf = pad_gpio_in; - // This causes conflict if output and input drivers are both enabled. . . - // assign mgmt_gpio_in = (gpio_inenb == 1'b0) ? pad_gpio_in : 1'bz; - assign mgmt_gpio_in = (gpio_inenb == 1'b0 && gpio_outenb == 1'b1)? pad_gpio_in : 1'bz; - - assign pad_gpio_outenb = (mgmt_ena) ? ((mgmt_gpio_oeb == 1'b1) ? gpio_outenb : - 1'b0) : user_gpio_oeb; - assign pad_gpio_out = (mgmt_ena) ? - ((mgmt_gpio_oeb == 1'b1) ? - ((gpio_dm[2:1] == 2'b01) ? ~gpio_dm[0] : mgmt_gpio_out) : - mgmt_gpio_out) : - user_gpio_out; - - /* Buffer user_gpio_in with an enable that is set by the user domain vccd */ - - gpio_logic_high gpio_logic_high ( -`ifdef USE_POWER_PINS - .vccd1(vccd1), - .vssd1(vssd1), -`endif - .gpio_logic1(gpio_logic1) - ); - - sky130_fd_sc_hd__einvp_8 gpio_in_buf ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(user_gpio_in), - .A(~gpio_in_unbuf), - .TE(gpio_logic1) - ); - - sky130_fd_sc_hd__conb_1 const_source ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .HI(one), - .LO(zero) - ); - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/gpio_logic_high.v b/caravel/rtl/gpio_logic_high.v deleted file mode 100644 index 2e4158e..0000000 --- a/caravel/rtl/gpio_logic_high.v +++ /dev/null
@@ -1,21 +0,0 @@ -module gpio_logic_high( - `ifdef USE_POWER_PINS - inout vccd1, - inout vssd1, - `endif - - output wire gpio_logic1 -); - - sky130_fd_sc_hd__conb_1 gpio_logic_high ( -`ifdef USE_POWER_PINS - .VPWR(vccd1), - .VGND(vssd1), - .VPB(vccd1), - .VNB(vssd1), -`endif - .HI(gpio_logic1), - .LO() - ); - -endmodule
diff --git a/caravel/rtl/gpio_wb.v b/caravel/rtl/gpio_wb.v deleted file mode 100644 index 9941fc9..0000000 --- a/caravel/rtl/gpio_wb.v +++ /dev/null
@@ -1,156 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -module gpio_wb # ( - parameter BASE_ADR = 32'h 2100_0000, - parameter GPIO_DATA = 8'h 00, - parameter GPIO_ENA = 8'h 04, - parameter GPIO_PU = 8'h 08, - parameter GPIO_PD = 8'h 0c -) ( - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_dat_i, - input [31:0] wb_adr_i, - input [3:0] wb_sel_i, - input wb_cyc_i, - input wb_stb_i, - input wb_we_i, - - output [31:0] wb_dat_o, - output wb_ack_o, - - input gpio_in_pad, - output gpio, - output gpio_oeb, - output gpio_pu, - output gpio_pd -); - - wire resetn; - wire valid; - wire ready; - wire [3:0] iomem_we; - - assign resetn = ~wb_rst_i; - assign valid = wb_stb_i && wb_cyc_i; - - assign iomem_we = wb_sel_i & {4{wb_we_i}}; - assign wb_ack_o = ready; - - gpio #( - .BASE_ADR(BASE_ADR), - .GPIO_DATA(GPIO_DATA), - .GPIO_ENA(GPIO_ENA), - .GPIO_PD(GPIO_PD), - .GPIO_PU(GPIO_PU) - ) gpio_ctrl ( - .clk(wb_clk_i), - .resetn(resetn), - - .gpio_in_pad(gpio_in_pad), - - .iomem_addr(wb_adr_i), - .iomem_valid(valid), - .iomem_wstrb(iomem_we[0]), - .iomem_wdata(wb_dat_i), - .iomem_rdata(wb_dat_o), - .iomem_ready(ready), - - .gpio(gpio), - .gpio_oeb(gpio_oeb), - .gpio_pu(gpio_pu), - .gpio_pd(gpio_pd) - ); - -endmodule - -module gpio #( - parameter BASE_ADR = 32'h 2100_0000, - parameter GPIO_DATA = 8'h 00, - parameter GPIO_ENA = 8'h 04, - parameter GPIO_PU = 8'h 08, - parameter GPIO_PD = 8'h 0c -) ( - input clk, - input resetn, - - input gpio_in_pad, - - input [31:0] iomem_addr, - input iomem_valid, - input iomem_wstrb, - input [31:0] iomem_wdata, - output reg [31:0] iomem_rdata, - output reg iomem_ready, - - output gpio, - output gpio_oeb, - output gpio_pu, - output gpio_pd -); - - reg gpio; // GPIO output data - reg gpio_pu; // GPIO pull-up enable - reg gpio_pd; // GPIO pull-down enable - reg gpio_oeb; // GPIO output enable (sense negative) - - wire gpio_sel; - wire gpio_oeb_sel; - wire gpio_pu_sel; - wire gpio_pd_sel; - - assign gpio_sel = (iomem_addr[7:0] == GPIO_DATA); - assign gpio_oeb_sel = (iomem_addr[7:0] == GPIO_ENA); - assign gpio_pu_sel = (iomem_addr[7:0] == GPIO_PU); - assign gpio_pd_sel = (iomem_addr[7:0] == GPIO_PD); - - always @(posedge clk) begin - if (!resetn) begin - gpio <= 0; - gpio_oeb <= 16'hffff; - gpio_pu <= 0; - gpio_pd <= 0; - end else begin - iomem_ready <= 0; - if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin - iomem_ready <= 1'b 1; - - if (gpio_sel) begin - iomem_rdata <= {30'd0, gpio, gpio_in_pad}; - if (iomem_wstrb) gpio <= iomem_wdata[0]; - - end else if (gpio_oeb_sel) begin - iomem_rdata <= {31'd0, gpio_oeb}; - if (iomem_wstrb) gpio_oeb <= iomem_wdata[0]; - - end else if (gpio_pu_sel) begin - iomem_rdata <= {31'd0, gpio_pu}; - if (iomem_wstrb) gpio_pu <= iomem_wdata[0]; - - end else if (gpio_pd_sel) begin - iomem_rdata <= {31'd0, gpio_pd}; - if (iomem_wstrb) gpio_pd <= iomem_wdata[0]; - - end - - end - end - end - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/housekeeping_spi.v b/caravel/rtl/housekeeping_spi.v deleted file mode 100644 index 7ed3b2f..0000000 --- a/caravel/rtl/housekeeping_spi.v +++ /dev/null
@@ -1,500 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -//------------------------------------- -// SPI controller for Caravel (PicoSoC) -//------------------------------------- -// Written by Tim Edwards -// efabless, inc. September 27, 2020 -//------------------------------------- - -//----------------------------------------------------------- -// This is a standalone slave SPI for the caravel chip that is -// intended to be independent of the picosoc and independent -// of all IP blocks except the power-on-reset. This SPI has -// register outputs controlling the functions that critically -// affect operation of the picosoc and so cannot be accessed -// from the picosoc itself. This includes the PLL enables -// and trim, and the crystal oscillator enable. It also has -// a general reset for the picosoc, an IRQ input, a bypass for -// the entire crystal oscillator and PLL chain, the -// manufacturer and product IDs and product revision number. -// To be independent of the 1.8V regulator, the slave SPI is -// synthesized with the 3V digital library and runs off of -// the 3V supply. -// -// This module is designed to be decoupled from the chip -// padframe and redirected to the wishbone bus under -// register control from the management SoC, such that the -// contents can be accessed from the management core via the -// SPI master. -// -//----------------------------------------------------------- - -//------------------------------------------------------------ -// Caravel defined registers: -// Register 0: SPI status and control (unused & reserved) -// Register 1 and 2: Manufacturer ID (0x0456) (readonly) -// Register 3: Product ID (= 16) (readonly) -// Register 4-7: Mask revision (readonly) --- Externally programmed -// with via programming. Via programmed with a script to match -// each customer ID. -// -// Register 8: PLL enables (2 bits) -// Register 9: PLL bypass (1 bit) -// Register 10: IRQ (1 bit) -// Register 11: reset (1 bit) -// Register 12: trap (1 bit) (readonly) -// Register 13-16: PLL trim (26 bits) -// Register 17: PLL output divider (3 bits) -// Register 18: PLL feedback divider (5 bits) -//------------------------------------------------------------ - -module housekeeping_spi( -`ifdef USE_POWER_PINS - vdd, vss, -`endif - RSTB, SCK, SDI, CSB, SDO, sdo_enb, - pll_ena, pll_dco_ena, pll_div, pll_sel, - pll90_sel, pll_trim, pll_bypass, irq, reset, - trap, mask_rev_in, - pass_thru_mgmt_reset, pass_thru_user_reset, - pass_thru_mgmt_sck, pass_thru_mgmt_csb, - pass_thru_mgmt_sdi, pass_thru_mgmt_sdo, - pass_thru_user_sck, pass_thru_user_csb, - pass_thru_user_sdi, pass_thru_user_sdo -); - -`ifdef USE_POWER_PINS - inout vdd; // 3.3V supply - inout vss; // common ground -`endif - - input RSTB; // from padframe - - input SCK; // from padframe - input SDI; // from padframe - input CSB; // from padframe - output SDO; // to padframe - output sdo_enb; // to padframe - - output pll_ena; - output pll_dco_ena; - output [4:0] pll_div; - output [2:0] pll_sel; - output [2:0] pll90_sel; - output [25:0] pll_trim; - output pll_bypass; - output irq; - output reset; - input trap; - input [31:0] mask_rev_in; // metal programmed; 3.3V domain - - // Pass-through programming mode for management area SPI flash - output pass_thru_mgmt_reset; - output pass_thru_user_reset; - output pass_thru_mgmt_sck; - output pass_thru_mgmt_csb; - output pass_thru_mgmt_sdi; - input pass_thru_mgmt_sdo; - - // Pass-through programming mode for user area SPI flash - output pass_thru_user_sck; - output pass_thru_user_csb; - output pass_thru_user_sdi; - input pass_thru_user_sdo; - - reg [25:0] pll_trim; - reg [4:0] pll_div; - reg [2:0] pll_sel; - reg [2:0] pll90_sel; - reg pll_dco_ena; - reg pll_ena; - reg pll_bypass; - reg reset_reg; - reg irq; - - wire [7:0] odata; - wire [7:0] idata; - wire [7:0] iaddr; - - wire trap; - wire rdstb; - wire wrstb; - wire pass_thru_mgmt; // Mode detected by spi_slave - wire pass_thru_mgmt_delay; - wire pass_thru_user; // Mode detected by spi_slave - wire pass_thru_user_delay; - wire loc_sdo; - - // Pass-through mode handling. Signals may only be applied when the - // core processor is in reset. - - assign pass_thru_mgmt_csb = ~pass_thru_mgmt_delay; - assign pass_thru_mgmt_sck = (pass_thru_mgmt ? SCK : 1'b0); - assign pass_thru_mgmt_sdi = (pass_thru_mgmt_delay ? SDI : 1'b0); - - assign pass_thru_user_csb = ~pass_thru_user_delay; - assign pass_thru_user_sck = (pass_thru_user ? SCK : 1'b0); - assign pass_thru_user_sdi = (pass_thru_user_delay ? SDI : 1'b0); - - assign SDO = pass_thru_mgmt ? pass_thru_mgmt_sdo : - pass_thru_user ? pass_thru_user_sdo : loc_sdo; - assign reset = pass_thru_mgmt_reset ? 1'b1 : reset_reg; - - // Instantiate the SPI slave module - - housekeeping_spi_slave U1 ( - .reset(~RSTB), - .SCK(SCK), - .SDI(SDI), - .CSB(CSB), - .SDO(loc_sdo), - .sdoenb(sdo_enb), - .idata(odata), - .odata(idata), - .oaddr(iaddr), - .rdstb(rdstb), - .wrstb(wrstb), - .pass_thru_mgmt(pass_thru_mgmt), - .pass_thru_mgmt_delay(pass_thru_mgmt_delay), - .pass_thru_user(pass_thru_user), - .pass_thru_user_delay(pass_thru_user_delay), - .pass_thru_mgmt_reset(pass_thru_mgmt_reset), - .pass_thru_user_reset(pass_thru_user_reset) - ); - - wire [11:0] mfgr_id; - wire [7:0] prod_id; - wire [31:0] mask_rev; - - assign mfgr_id = 12'h456; // Hard-coded - assign prod_id = 8'h10; // Hard-coded - assign mask_rev = mask_rev_in; // Copy in to out. - - // Send register contents to odata on SPI read command - // All values are 1-4 bits and no shadow registers are required. - - assign odata = - (iaddr == 8'h00) ? 8'h00 : // SPI status (fixed) - (iaddr == 8'h01) ? {4'h0, mfgr_id[11:8]} : // Manufacturer ID (fixed) - (iaddr == 8'h02) ? mfgr_id[7:0] : // Manufacturer ID (fixed) - (iaddr == 8'h03) ? prod_id : // Product ID (fixed) - (iaddr == 8'h04) ? mask_rev[31:24] : // Mask rev (metal programmed) - (iaddr == 8'h05) ? mask_rev[23:16] : // Mask rev (metal programmed) - (iaddr == 8'h06) ? mask_rev[15:8] : // Mask rev (metal programmed) - (iaddr == 8'h07) ? mask_rev[7:0] : // Mask rev (metal programmed) - - (iaddr == 8'h08) ? {6'b000000, pll_dco_ena, pll_ena} : - (iaddr == 8'h09) ? {7'b0000000, pll_bypass} : - (iaddr == 8'h0a) ? {7'b0000000, irq} : - (iaddr == 8'h0b) ? {7'b0000000, reset} : - (iaddr == 8'h0c) ? {7'b0000000, trap} : - (iaddr == 8'h0d) ? pll_trim[7:0] : - (iaddr == 8'h0e) ? pll_trim[15:8] : - (iaddr == 8'h0f) ? pll_trim[23:16] : - (iaddr == 8'h10) ? {6'b000000, pll_trim[25:24]} : - (iaddr == 8'h11) ? {2'b00, pll90_sel, pll_sel} : - (iaddr == 8'h12) ? {3'b000, pll_div} : - 8'h00; // Default - - // Register mapping and I/O to slave module - - always @(posedge SCK or negedge RSTB) begin - if (RSTB == 1'b0) begin - // Set trim for PLL at (almost) slowest rate (~90MHz). However, - // pll_trim[12] must be set to zero for proper startup. - pll_trim <= 26'b11111111111110111111111111; - pll_sel <= 3'b010; // Default output divider divide-by-2 - pll90_sel <= 3'b010; // Default secondary output divider divide-by-2 - pll_div <= 5'b00100; // Default feedback divider divide-by-8 - pll_dco_ena <= 1'b1; // Default free-running PLL - pll_ena <= 1'b0; // Default PLL turned off - pll_bypass <= 1'b1; // Default bypass mode (don't use PLL) - irq <= 1'b0; - reset_reg <= 1'b0; - end else if (wrstb == 1'b1) begin - case (iaddr) - 8'h08: begin - pll_ena <= idata[0]; - pll_dco_ena <= idata[1]; - end - 8'h09: begin - pll_bypass <= idata[0]; - end - 8'h0a: begin - irq <= idata[0]; - end - 8'h0b: begin - reset_reg <= idata[0]; - end - // Register 0xc is read-only - 8'h0d: begin - pll_trim[7:0] <= idata; - end - 8'h0e: begin - pll_trim[15:8] <= idata; - end - 8'h0f: begin - pll_trim[23:16] <= idata; - end - 8'h10: begin - pll_trim[25:24] <= idata[1:0]; - end - 8'h11: begin - pll_sel <= idata[2:0]; - pll90_sel <= idata[5:3]; - end - 8'h12: begin - pll_div <= idata[4:0]; - end - endcase // (iaddr) - end - end -endmodule // housekeeping_spi - -//------------------------------------------------------ -// housekeeping_spi_slave.v -//------------------------------------------------------ -// General purpose SPI slave module for the Caravel chip -//------------------------------------------------------ -// Written by Tim Edwards -// efabless, inc., September 28, 2020 -//------------------------------------------------ -// This file is distributed free and open source -//------------------------------------------------ - -// SCK --- Clock input -// SDI --- Data input -// SDO --- Data output -// CSB --- Chip select (sense negative) -// idata --- Data from chip to transmit out, in 8 bits -// odata --- Input data to chip, in 8 bits -// addr --- Decoded address to upstream circuits -// rdstb --- Read strobe, tells upstream circuit to supply next byte to idata -// wrstb --- Write strobe, tells upstream circuit to latch odata. - -// Data format (general purpose): -// 8 bit format -// 1st byte: Command word (see below) -// 2nd byte: Address word (register 0 to 255) -// 3rd byte: Data word (value 0 to 255) - -// Command format: -// 00000000 No operation -// 10000000 Write until CSB raised -// 01000000 Read until CSB raised -// 11000000 Simultaneous read/write until CSB raised -// 11000100 Pass-through read/write to management area flash SPI until CSB raised -// 11000010 Pass-through read/write to user area flash SPI until CSB raised -// wrnnn000 Read/write as above, for nnn = 1 to 7 bytes, then terminate - -// Lower three bits are reserved for future use. -// All serial bytes are read and written msb first. - -// Fixed control and status registers - -// Address 0 is reserved and contains flags for SPI mode. This is -// currently undefined and is always value 0. -// Address 1 is reserved and contains manufacturer ID low 8 bits. -// Address 2 is reserved and contains manufacturer ID high 4 bits. -// Address 3 is reserved and contains product ID (8 bits). -// Addresses 4 to 7 are reserved and contain the mask ID (32 bits). -// Addresses 8 to 255 are available for general purpose use. - -`define COMMAND 3'b000 -`define ADDRESS 3'b001 -`define DATA 3'b010 -`define USERPASS 3'b100 -`define MGMTPASS 3'b101 - -module housekeeping_spi_slave(reset, SCK, SDI, CSB, SDO, - sdoenb, idata, odata, oaddr, rdstb, wrstb, - pass_thru_mgmt, pass_thru_mgmt_delay, - pass_thru_user, pass_thru_user_delay, - pass_thru_mgmt_reset, pass_thru_user_reset); - - input reset; - input SCK; - input SDI; - input CSB; - output SDO; - output sdoenb; - input [7:0] idata; - output [7:0] odata; - output [7:0] oaddr; - output rdstb; - output wrstb; - output pass_thru_mgmt; - output pass_thru_mgmt_delay; - output pass_thru_user; - output pass_thru_user_delay; - output pass_thru_mgmt_reset; - output pass_thru_user_reset; - - reg [7:0] addr; - reg wrstb; - reg rdstb; - reg sdoenb; - reg [2:0] state; - reg [2:0] count; - reg writemode; - reg readmode; - reg [2:0] fixed; - wire [7:0] odata; - reg [6:0] predata; - wire [7:0] oaddr; - reg [7:0] ldata; - reg pass_thru_mgmt; - reg pass_thru_mgmt_delay; - reg pre_pass_thru_mgmt; - reg pass_thru_user; - reg pass_thru_user_delay; - reg pre_pass_thru_user; - wire csb_reset; - - assign odata = {predata, SDI}; - assign oaddr = (state == `ADDRESS) ? {addr[6:0], SDI} : addr; - assign SDO = ldata[7]; - assign csb_reset = CSB | reset; - assign pass_thru_mgmt_reset = pass_thru_mgmt_delay | pre_pass_thru_mgmt; - assign pass_thru_user_reset = pass_thru_user_delay | pre_pass_thru_user; - - // Readback data is captured on the falling edge of SCK so that - // it is guaranteed valid at the next rising edge. - always @(negedge SCK or posedge csb_reset) begin - if (csb_reset == 1'b1) begin - wrstb <= 1'b0; - ldata <= 8'b00000000; - sdoenb <= 1'b1; - end else begin - - // After CSB low, 1st SCK starts command - - if (state == `DATA) begin - if (readmode == 1'b1) begin - sdoenb <= 1'b0; - if (count == 3'b000) begin - ldata <= idata; - end else begin - ldata <= {ldata[6:0], 1'b0}; // Shift out - end - end else begin - sdoenb <= 1'b1; - end - - // Apply write strobe on SCK negative edge on the next-to-last - // data bit so that it updates data on the rising edge of SCK - // on the last data bit. - - if (count == 3'b111) begin - if (writemode == 1'b1) begin - wrstb <= 1'b1; - end - end else begin - wrstb <= 1'b0; - end - end else if (state == `MGMTPASS || state == `USERPASS) begin - wrstb <= 1'b0; - sdoenb <= 1'b0; - end else begin - wrstb <= 1'b0; - sdoenb <= 1'b1; - end // ! state `DATA - end // ! csb_reset - end // always @ ~SCK - - always @(posedge SCK or posedge csb_reset) begin - if (csb_reset == 1'b1) begin - // Default state on reset - addr <= 8'h00; - rdstb <= 1'b0; - predata <= 7'b0000000; - state <= `COMMAND; - count <= 3'b000; - readmode <= 1'b0; - writemode <= 1'b0; - fixed <= 3'b000; - pass_thru_mgmt <= 1'b0; - pass_thru_mgmt_delay <= 1'b0; - pre_pass_thru_mgmt <= 1'b0; - pass_thru_user = 1'b0; - pass_thru_user_delay <= 1'b0; - pre_pass_thru_user <= 1'b0; - end else begin - // After csb_reset low, 1st SCK starts command - if (state == `COMMAND) begin - rdstb <= 1'b0; - count <= count + 1; - if (count == 3'b000) begin - writemode <= SDI; - end else if (count == 3'b001) begin - readmode <= SDI; - end else if (count < 3'b101) begin - fixed <= {fixed[1:0], SDI}; - end else if (count == 3'b101) begin - pre_pass_thru_mgmt <= SDI; - end else if (count == 3'b110) begin - pre_pass_thru_user <= SDI; - pass_thru_mgmt_delay <= pre_pass_thru_mgmt; - end else if (count == 3'b111) begin - pass_thru_user_delay <= pre_pass_thru_user; - if (pre_pass_thru_mgmt == 1'b1) begin - state <= `MGMTPASS; - pre_pass_thru_mgmt <= 1'b0; - end else if (pre_pass_thru_user == 1'b1) begin - state <= `USERPASS; - pre_pass_thru_user <= 1'b0; - end else begin - state <= `ADDRESS; - end - end - end else if (state == `ADDRESS) begin - count <= count + 1; - addr <= {addr[6:0], SDI}; - if (count == 3'b111) begin - if (readmode == 1'b1) begin - rdstb <= 1'b1; - end - state <= `DATA; - end else begin - rdstb <= 1'b0; - end - end else if (state == `DATA) begin - predata <= {predata[6:0], SDI}; - count <= count + 1; - if (count == 3'b111) begin - if (fixed == 3'b001) begin - state <= `COMMAND; - end else if (fixed != 3'b000) begin - fixed <= fixed - 1; - addr <= addr + 1; // Auto increment address (fixed) - end else begin - addr <= addr + 1; // Auto increment address (streaming) - end - end else begin - rdstb <= 1'b0; - end - end else if (state == `MGMTPASS) begin - pass_thru_mgmt <= 1'b1; - end else if (state == `USERPASS) begin - pass_thru_user <= 1'b1; - end // ! state `DATA | `MGMTPASS | `USERPASS - end // ! csb_reset - end // always @ SCK - -endmodule // housekeeping_spi_slave -`default_nettype wire
diff --git a/caravel/rtl/la_wb.v b/caravel/rtl/la_wb.v deleted file mode 100644 index fbbc77c..0000000 --- a/caravel/rtl/la_wb.v +++ /dev/null
@@ -1,305 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -module la_wb # ( - parameter BASE_ADR = 32'h 2200_0000, - parameter LA_DATA_0 = 8'h00, - parameter LA_DATA_1 = 8'h04, - parameter LA_DATA_2 = 8'h08, - parameter LA_DATA_3 = 8'h0c, - parameter LA_OENB_0 = 8'h10, - parameter LA_OENB_1 = 8'h14, - parameter LA_OENB_2 = 8'h18, - parameter LA_OENB_3 = 8'h1c, - parameter LA_IENA_0 = 8'h20, - parameter LA_IENA_1 = 8'h24, - parameter LA_IENA_2 = 8'h28, - parameter LA_IENA_3 = 8'h2c, - parameter LA_SAMPLE = 8'h30 -) ( - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_dat_i, - input [31:0] wb_adr_i, - input [3:0] wb_sel_i, - input wb_cyc_i, - input wb_stb_i, - input wb_we_i, - - output [31:0] wb_dat_o, - output wb_ack_o, - - input [127:0] la_data_in, // From MPRJ - output [127:0] la_data, - output [127:0] la_oenb, - output [127:0] la_iena -); - - wire resetn; - wire valid; - wire ready; - wire [3:0] iomem_we; - - assign resetn = ~wb_rst_i; - assign valid = wb_stb_i && wb_cyc_i; - - assign iomem_we = wb_sel_i & {4{wb_we_i}}; - assign wb_ack_o = ready; - - la #( - .BASE_ADR(BASE_ADR), - .LA_DATA_0(LA_DATA_0), - .LA_DATA_1(LA_DATA_1), - .LA_DATA_2(LA_DATA_2), - .LA_DATA_3(LA_DATA_3), - .LA_OENB_0(LA_OENB_0), - .LA_OENB_1(LA_OENB_1), - .LA_OENB_2(LA_OENB_2), - .LA_OENB_3(LA_OENB_3), - .LA_IENA_0(LA_IENA_0), - .LA_IENA_1(LA_IENA_1), - .LA_IENA_2(LA_IENA_2), - .LA_IENA_3(LA_IENA_3), - .LA_SAMPLE(LA_SAMPLE) - ) la_ctrl ( - .clk(wb_clk_i), - .resetn(resetn), - .iomem_addr(wb_adr_i), - .iomem_valid(valid), - .iomem_wstrb(iomem_we), - .iomem_wdata(wb_dat_i), - .iomem_rdata(wb_dat_o), - .iomem_ready(ready), - .la_data_in(la_data_in), - .la_data(la_data), - .la_oenb(la_oenb), - .la_iena(la_iena) - ); - -endmodule - -module la #( - parameter BASE_ADR = 32'h 2200_0000, - parameter LA_DATA_0 = 8'h00, - parameter LA_DATA_1 = 8'h04, - parameter LA_DATA_2 = 8'h08, - parameter LA_DATA_3 = 8'h0c, - parameter LA_OENB_0 = 8'h10, - parameter LA_OENB_1 = 8'h14, - parameter LA_OENB_2 = 8'h18, - parameter LA_OENB_3 = 8'h1c, - parameter LA_IENA_0 = 8'h20, - parameter LA_IENA_1 = 8'h24, - parameter LA_IENA_2 = 8'h28, - parameter LA_IENA_3 = 8'h2c, - parameter LA_SAMPLE = 8'h30 -) ( - input clk, - input resetn, - - input [31:0] iomem_addr, - input iomem_valid, - input [3:0] iomem_wstrb, - input [31:0] iomem_wdata, - - output reg [31:0] iomem_rdata, - output reg iomem_ready, - - input [127:0] la_data_in, // From MPRJ - output [127:0] la_data, // To MPRJ - output [127:0] la_oenb, - output [127:0] la_iena -); - - reg [31:0] la_data_0; - reg [31:0] la_data_1; - reg [31:0] la_data_2; - reg [31:0] la_data_3; - - reg [31:0] la_oenb_0; - reg [31:0] la_oenb_1; - reg [31:0] la_oenb_2; - reg [31:0] la_oenb_3; - - reg [31:0] la_iena_0; - reg [31:0] la_iena_1; - reg [31:0] la_iena_2; - reg [31:0] la_iena_3; - - wire [3:0] la_data_sel; - wire [3:0] la_oenb_sel; - wire [3:0] la_iena_sel; - wire la_sample_sel; - - wire [31:0] la_sample_mask_0; - wire [31:0] la_sample_mask_1; - wire [31:0] la_sample_mask_2; - wire [31:0] la_sample_mask_3; - - assign la_data = {la_data_3, la_data_2, la_data_1, la_data_0}; - assign la_oenb = {la_oenb_3, la_oenb_2, la_oenb_1, la_oenb_0}; - assign la_iena = {la_iena_3, la_iena_2, la_iena_1, la_iena_0}; - - assign la_data_sel = { - (iomem_addr[7:0] == LA_DATA_3), - (iomem_addr[7:0] == LA_DATA_2), - (iomem_addr[7:0] == LA_DATA_1), - (iomem_addr[7:0] == LA_DATA_0) - }; - - assign la_oenb_sel = { - (iomem_addr[7:0] == LA_OENB_3), - (iomem_addr[7:0] == LA_OENB_2), - (iomem_addr[7:0] == LA_OENB_1), - (iomem_addr[7:0] == LA_OENB_0) - }; - - assign la_iena_sel = { - (iomem_addr[7:0] == LA_IENA_3), - (iomem_addr[7:0] == LA_IENA_2), - (iomem_addr[7:0] == LA_IENA_1), - (iomem_addr[7:0] == LA_IENA_0) - }; - - assign la_sample_sel = (iomem_addr[7:0] == LA_SAMPLE); - assign la_sample_mask_3 = (la_oenb_3 & la_iena_3); - assign la_sample_mask_2 = (la_oenb_2 & la_iena_2); - assign la_sample_mask_1 = (la_oenb_1 & la_iena_1); - assign la_sample_mask_0 = (la_oenb_0 & la_iena_0); - - always @(posedge clk) begin - if (!resetn) begin - la_data_0 <= 0; - la_data_1 <= 0; - la_data_2 <= 0; - la_data_3 <= 0; - la_oenb_0 <= 32'hFFFF_FFFF; // default is tri-state buff disabled - la_oenb_1 <= 32'hFFFF_FFFF; - la_oenb_2 <= 32'hFFFF_FFFF; - la_oenb_3 <= 32'hFFFF_FFFF; - la_iena_0 <= 32'h0000_0000; // default is grounded input - la_iena_1 <= 32'h0000_0000; - la_iena_2 <= 32'h0000_0000; - la_iena_3 <= 32'h0000_0000; - end else begin - iomem_ready <= 0; - if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin - iomem_ready <= 1'b 1; - - /* NOTE: Data in and out are independent channels */ - - if (la_data_sel[0]) begin - iomem_rdata <= la_data_in[31:0]; - - if (iomem_wstrb[0]) la_data_0[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_data_0[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_data_0[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_data_0[31:24] <= iomem_wdata[31:24]; - - end else if (la_data_sel[1]) begin - iomem_rdata <= la_data_in[63:32]; - - if (iomem_wstrb[0]) la_data_1[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_data_1[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_data_1[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_data_1[31:24] <= iomem_wdata[31:24]; - - end else if (la_data_sel[2]) begin - iomem_rdata <= la_data_in[95:64]; - - if (iomem_wstrb[0]) la_data_2[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_data_2[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_data_2[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_data_2[31:24] <= iomem_wdata[31:24]; - - end else if (la_data_sel[3]) begin - iomem_rdata <= la_data_in[127:96]; - - if (iomem_wstrb[0]) la_data_3[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_data_3[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_data_3[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_data_3[31:24] <= iomem_wdata[31:24]; - end else if (la_oenb_sel[0]) begin - iomem_rdata <= la_oenb_0; - - if (iomem_wstrb[0]) la_oenb_0[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_oenb_0[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_oenb_0[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_oenb_0[31:24] <= iomem_wdata[31:24]; - end else if (la_oenb_sel[1]) begin - iomem_rdata <= la_oenb_1; - - if (iomem_wstrb[0]) la_oenb_1[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_oenb_1[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_oenb_1[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_oenb_1[31:24] <= iomem_wdata[31:24]; - end else if (la_oenb_sel[2]) begin - iomem_rdata <= la_oenb_2; - - if (iomem_wstrb[0]) la_oenb_2[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_oenb_2[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_oenb_2[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_oenb_2[31:24] <= iomem_wdata[31:24]; - end else if (la_oenb_sel[3]) begin - iomem_rdata <= la_oenb_3; - - if (iomem_wstrb[0]) la_oenb_3[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_oenb_3[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_oenb_3[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_oenb_3[31:24] <= iomem_wdata[31:24]; - end else if (la_iena_sel[0]) begin - iomem_rdata <= la_iena_0; - - if (iomem_wstrb[0]) la_iena_0[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_iena_0[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_iena_0[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_iena_0[31:24] <= iomem_wdata[31:24]; - end else if (la_iena_sel[1]) begin - iomem_rdata <= la_iena_1; - - if (iomem_wstrb[0]) la_iena_1[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_iena_1[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_iena_1[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_iena_1[31:24] <= iomem_wdata[31:24]; - end else if (la_iena_sel[2]) begin - iomem_rdata <= la_iena_2; - - if (iomem_wstrb[0]) la_iena_2[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_iena_2[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_iena_2[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_iena_2[31:24] <= iomem_wdata[31:24]; - end else if (la_iena_sel[3]) begin - iomem_rdata <= la_iena_3; - - if (iomem_wstrb[0]) la_iena_3[ 7: 0] <= iomem_wdata[ 7: 0]; - if (iomem_wstrb[1]) la_iena_3[15: 8] <= iomem_wdata[15: 8]; - if (iomem_wstrb[2]) la_iena_3[23:16] <= iomem_wdata[23:16]; - if (iomem_wstrb[3]) la_iena_3[31:24] <= iomem_wdata[31:24]; - end else if (la_sample_sel) begin - /* Simultaneous data capture: Sample all inputs */ - /* for which input is enabled and output is disabled. */ - la_data_0 <= la_data_in[31:0] & la_sample_mask_0; - la_data_1 <= la_data_in[63:32] & la_sample_mask_1; - la_data_2 <= la_data_in[95:64] & la_sample_mask_2; - la_data_3 <= la_data_in[127:96] & la_sample_mask_3; - end - end - end - end - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/mem_wb.v b/caravel/rtl/mem_wb.v deleted file mode 100644 index 276cc36..0000000 --- a/caravel/rtl/mem_wb.v +++ /dev/null
@@ -1,141 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -module mem_wb ( -`ifdef USE_POWER_PINS - input VPWR, - input VGND, -`endif - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_adr_i, - input [31:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input wb_cyc_i, - input wb_stb_i, - - output wb_ack_o, - output [31:0] wb_dat_o - -); - - localparam ADR_WIDTH = $clog2(`MEM_WORDS); - - wire valid; - wire ram_wen; - wire [3:0] wen; // write enable - - assign valid = wb_cyc_i & wb_stb_i; - assign ram_wen = wb_we_i && valid; - - assign wen = wb_sel_i & {4{ram_wen}} ; - - /* - Ack Generation - - write transaction: asserted upon receiving adr_i & dat_i - - read transaction : asserted one clock cycle after receiving the adr_i & dat_i - */ - - reg wb_ack_read; - reg wb_ack_o; - - always @(posedge wb_clk_i) begin - if (wb_rst_i == 1'b 1) begin - wb_ack_read <= 1'b0; - wb_ack_o <= 1'b0; - end else begin - // wb_ack_read <= {2{valid}} & {1'b1, wb_ack_read[1]}; - wb_ack_o <= wb_we_i? (valid & !wb_ack_o): wb_ack_read; - wb_ack_read <= (valid & !wb_ack_o) & !wb_ack_read; - end - end - - soc_mem -`ifndef USE_OPENRAM - #( - .WORDS(`MEM_WORDS), - .ADR_WIDTH(ADR_WIDTH) - ) -`endif - mem ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .clk(wb_clk_i), - .ena(valid), - .wen(wen), - .addr(wb_adr_i[ADR_WIDTH+1:2]), - .wdata(wb_dat_i), - .rdata(wb_dat_o) - ); - -endmodule - -module soc_mem -`ifndef USE_OPENRAM -#( - parameter integer WORDS = 256, - parameter ADR_WIDTH = 8 -) -`endif - ( -`ifdef USE_POWER_PINS - input VPWR, - input VGND, -`endif - input clk, - input ena, - input [3:0] wen, - input [ADR_WIDTH-1:0] addr, - input [31:0] wdata, - output[31:0] rdata -); - -`ifndef USE_OPENRAM - DFFRAM #(.WSIZE(`DFFRAM_WSIZE), .USE_LATCH(`DFFRAM_USE_LATCH)) SRAM ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .CLK(clk), - .WE(wen), - .EN(ena), - .Di(wdata), - .Do(rdata), - // 8-bit address if using the default custom DFF RAM - .A(addr) - ); -`else - - /* Using Port 0 Only - Size: 1KB, 256x32 bits */ - //sram_1rw1r_32_256_8_scn4m_subm - sram_1rw1r_32_256_8_sky130 SRAM( - .clk0(clk), - .csb0(~ena), - .web0(~|wen), - .wmask0(wen), - .addr0(addr[7:0]), - .din0(wdata), - .dout0(rdata) - ); - -`endif - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/mgmt_core.v b/caravel/rtl/mgmt_core.v deleted file mode 100644 index 31ca5ad..0000000 --- a/caravel/rtl/mgmt_core.v +++ /dev/null
@@ -1,373 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -module mgmt_core ( -`ifdef USE_POWER_PINS - inout VPWR, - inout VGND, -`endif - // GPIO (dedicated pad) - output gpio_out_pad, // Connect to out on gpio pad - input gpio_in_pad, // Connect to in on gpio pad - output gpio_mode0_pad, // Connect to dm[0] on gpio pad - output gpio_mode1_pad, // Connect to dm[2] on gpio pad - output gpio_outenb_pad, // Connect to oe_n on gpio pad - output gpio_inenb_pad, // Connect to inp_dis on gpio pad - // Flash memory control (SPI master) - output flash_csb, - output flash_clk, - output flash_csb_oeb, - output flash_clk_oeb, - output flash_io0_oeb, - output flash_io1_oeb, - output flash_io2_oeb, // through GPIO 36 - output flash_io3_oeb, // through GPIO 37 - output flash_csb_ieb, - output flash_clk_ieb, - output flash_io0_ieb, - output flash_io1_ieb, - output flash_io0_do, - output flash_io1_do, - input flash_io0_di, - input flash_io1_di, - // Master reset - input resetb, - input porb, - // Clocking - input clock, - // LA signals - input [127:0] la_input, // From User Project to cpu - output [127:0] la_output, // From CPU to User Project - output [127:0] la_oenb, // LA output enable - output [127:0] la_iena, // LA input enable - // Housekeeping SPI - output sdo_out, - output sdo_outenb, - // JTAG - output jtag_out, - output jtag_outenb, - // User Project Control Signals - input [`MPRJ_IO_PADS-1:0] mgmt_in_data, - output [`MPRJ_IO_PADS-1:0] mgmt_out_data, - output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out, - input mprj_vcc_pwrgood, - input mprj2_vcc_pwrgood, - input mprj_vdd_pwrgood, - input mprj2_vdd_pwrgood, - output mprj_io_loader_resetn, - output mprj_io_loader_clock, - output mprj_io_loader_data_1, - output mprj_io_loader_data_2, - // WB MI A (User project) - input mprj_ack_i, - input [31:0] mprj_dat_i, - output mprj_cyc_o, - output mprj_stb_o, - output mprj_we_o, - output [3:0] mprj_sel_o, - output [31:0] mprj_adr_o, - output [31:0] mprj_dat_o, - - output core_clk, - output user_clk, - output core_rstn, - input [2:0] user_irq, - output [2:0] user_irq_ena, - - // Metal programmed user ID / mask revision vector - input [31:0] mask_rev, - - // MGMT area R/W interface for mgmt RAM - output [`RAM_BLOCKS-1:0] mgmt_ena, - output [(`RAM_BLOCKS*4)-1:0] mgmt_wen_mask, - output [`RAM_BLOCKS-1:0] mgmt_wen, - output [7:0] mgmt_addr, - output [31:0] mgmt_wdata, - input [(`RAM_BLOCKS*32)-1:0] mgmt_rdata, - - // MGMT area RO interface for user RAM - output mgmt_ena_ro, - output [7:0] mgmt_addr_ro, - input [31:0] mgmt_rdata_ro -); - wire ext_clk_sel; - wire pll_clk, pll_clk90; - wire ext_reset; - wire hk_connect; - wire trap; - wire irq_spi; - - // JTAG (to be implemented) - wire jtag_out; - wire jtag_out_pre = 1'b0; - wire jtag_outenb = 1'b1; - wire jtag_oenb_state; - - // SDO - wire sdo_out; - wire sdo_out_pre; - wire sdo_oenb_state; - - // Housekeeping SPI vectors - wire [4:0] spi_pll_div; - wire [2:0] spi_pll_sel; - wire [2:0] spi_pll90_sel; - wire [25:0] spi_pll_trim; - - // All but the first two and last two IOs share the in and out data line - // and so the output data line must be high-impedence when the input is - // enabled. - - wire [`MPRJ_IO_PADS-1:0] mgmt_oeb_data; - wire [`MPRJ_IO_PADS-1:0] mgmt_out_predata; - - wire mgmt_mux_csb, mgmt_mux_sck, mgmt_mux_sdi; - wire pass_thru_user_csb, pass_thru_user_sck, pass_thru_user_sdi; - wire pass_thru_mgmt_sdo, pass_thru_mgmt_csb; - wire pass_thru_mgmt_sck, pass_thru_mgmt_sdi; - wire pass_thru_mgmt, pass_thru_user; - wire spi_pll_ena, spi_pll_dco_ena; - - // During external reset, data lines 8 to 10 are used by the user flash - // pass-through mode. - - assign mgmt_mux_csb = (pass_thru_user == 1'b1) ? - pass_thru_user_csb : mgmt_out_predata[8]; - assign mgmt_mux_sck = (pass_thru_user == 1'b1) ? - pass_thru_user_sck : mgmt_out_predata[9]; - assign mgmt_mux_sdi = (pass_thru_user == 1'b1) ? - pass_thru_user_sdi : mgmt_out_predata[10]; - - genvar i; - - generate - for (i = 0; i < 2; i = i + 1) begin - assign mgmt_out_data[i] = mgmt_out_predata[i]; - end - for (i = 2; i < 8; i = i + 1) begin - assign mgmt_out_data[i] = (mgmt_oeb_data[i]) ? 1'bz : mgmt_out_predata[i]; - end - assign mgmt_out_data[8] = (mgmt_oeb_data[8]) ? 1'bz : mgmt_mux_csb; - assign mgmt_out_data[9] = (mgmt_oeb_data[9]) ? 1'bz : mgmt_mux_sck; - assign mgmt_out_data[10] = (mgmt_oeb_data[10]) ? 1'bz : mgmt_mux_sdi; - for (i = 11; i < `MPRJ_IO_PADS-2; i = i + 1) begin - assign mgmt_out_data[i] = (mgmt_oeb_data[i]) ? 1'bz : mgmt_out_predata[i]; - end - for (i = `MPRJ_IO_PADS-2; i < `MPRJ_IO_PADS; i = i + 1) begin - assign mgmt_out_data[i] = mgmt_out_predata[i]; - end - endgenerate - - // Override default function for SDO and JTAG outputs if purposely - // set for override by the management SoC. - assign sdo_out = (sdo_oenb_state == 1'b0) ? mgmt_out_predata[1] : sdo_out_pre; - assign jtag_out = (jtag_oenb_state == 1'b0) ? mgmt_out_predata[0] : jtag_out_pre; - - caravel_clocking clocking( - `ifdef USE_POWER_PINS - .vdd1v8(VPWR), - .vss(VGND), - `endif - .ext_clk_sel(ext_clk_sel), - .ext_clk(clock), - .pll_clk(pll_clk), - .pll_clk90(pll_clk90), - .resetb(resetb), - .sel(spi_pll_sel), - .sel2(spi_pll90_sel), - .ext_reset(ext_reset), // From housekeeping SPI - .core_clk(core_clk), - .user_clk(user_clk), - .resetb_sync(core_rstn) - ); - - // These wires are defined in the SoC but are not being used because - // the SoC flash is reduced to a 2-pin I/O - wire flash_io2_oeb, flash_io3_oeb; - wire flash_io2_ieb, flash_io3_ieb; - wire flash_io2_di, flash_io3_di; - - // The following functions are connected to specific user project - // area pins, when under control of the management area (during - // startup, and when not otherwise programmed for the user project). - - // JTAG = jtag_out (inout) - // SDO = sdo_out (output) (shared with SPI master) - // SDI = mgmt_in_data[2] (input) (shared with SPI master) - // CSB = mgmt_in_data[3] (input) (shared with SPI master) - // SCK = mgmt_in_data[4] (input) (shared with SPI master) - // ser_rx = mgmt_in_data[5] (input) - // ser_tx = mgmt_out_data[6] (output) - // irq = mgmt_in_data[7] (input) - // flash_csb = mgmt_out_data[8] (output) (user area flash) - // flash_sck = mgmt_out_data[9] (output) (user area flash) - // flash_io0 = mgmt_in/out_data[10] (input) (user area flash) - // flash_io1 = mgmt_in/out_data[11] (output) (user area flash) - // irq2_pin = mgmt_in_data[12] (input) - // trap_mon = mgmt_in_data[13] (output) - // clk1_mon = mgmt_in_data[14] (output) - // clk2_mon = mgmt_in_data[15] (output) - - - // OEB lines for [0] and [1] are the only ones connected directly to - // the pad. All others have OEB controlled by the configuration bit - // in the control block. - - mgmt_soc soc ( - `ifdef USE_POWER_PINS - .vdd1v8(VPWR), - .vss(VGND), - `endif - .clk(core_clk), - .resetn(core_rstn), - .trap(trap), - // GPIO - .gpio_out_pad(gpio_out_pad), - .gpio_in_pad(gpio_in_pad), - .gpio_mode0_pad(gpio_mode0_pad), - .gpio_mode1_pad(gpio_mode1_pad), - .gpio_outenb_pad(gpio_outenb_pad), - .gpio_inenb_pad(gpio_inenb_pad), - .irq_spi(irq_spi), - // Flash - .flash_csb(flash_csb), - .flash_clk(flash_clk), - .flash_csb_oeb(flash_csb_oeb), - .flash_clk_oeb(flash_clk_oeb), - .flash_io0_oeb(flash_io0_oeb), - .flash_io1_oeb(flash_io1_oeb), - .flash_io2_oeb(flash_io2_oeb), - .flash_io3_oeb(flash_io3_oeb), - .flash_csb_ieb(flash_csb_ieb), - .flash_clk_ieb(flash_clk_ieb), - .flash_io0_ieb(flash_io0_ieb), - .flash_io1_ieb(flash_io1_ieb), - .flash_io2_ieb(flash_io2_ieb), - .flash_io3_ieb(flash_io3_ieb), - .flash_io0_do(flash_io0_do), - .flash_io1_do(flash_io1_do), - .flash_io0_di(flash_io0_di), - .flash_io1_di(flash_io1_di), - .flash_io2_di(flash_io2_di), - .flash_io3_di(flash_io3_di), - // SPI pass-through to/from SPI flash controller - .pass_thru_mgmt(pass_thru_mgmt), - .pass_thru_mgmt_csb(pass_thru_mgmt_csb), - .pass_thru_mgmt_sck(pass_thru_mgmt_sck), - .pass_thru_mgmt_sdi(pass_thru_mgmt_sdi), - .pass_thru_mgmt_sdo(pass_thru_mgmt_sdo), - // SDO and JTAG state for output override - .sdo_oenb_state(sdo_oenb_state), - .jtag_oenb_state(jtag_oenb_state), - // SPI master->slave direct connection - .hk_connect(hk_connect), - // Secondary clock (for monitoring) - .user_clk(user_clk), - // Logic Analyzer - .la_input(la_input), - .la_output(la_output), - .la_oenb(la_oenb), - .la_iena(la_iena), - // User Project I/O Configuration - .mprj_vcc_pwrgood(mprj_vcc_pwrgood), - .mprj2_vcc_pwrgood(mprj2_vcc_pwrgood), - .mprj_vdd_pwrgood(mprj_vdd_pwrgood), - .mprj2_vdd_pwrgood(mprj2_vdd_pwrgood), - .mprj_io_loader_resetn(mprj_io_loader_resetn), - .mprj_io_loader_clock(mprj_io_loader_clock), - .mprj_io_loader_data_1(mprj_io_loader_data_1), - .mprj_io_loader_data_2(mprj_io_loader_data_2), - // User project IRQ - .user_irq(user_irq), - .user_irq_ena(user_irq_ena), - // I/O data - .mgmt_in_data(mgmt_in_data), - .mgmt_out_data(mgmt_out_predata), - .mgmt_oeb_data(mgmt_oeb_data), - .pwr_ctrl_out(pwr_ctrl_out), - // User Project Slave ports (WB MI A) - .mprj_cyc_o(mprj_cyc_o), - .mprj_stb_o(mprj_stb_o), - .mprj_we_o(mprj_we_o), - .mprj_sel_o(mprj_sel_o), - .mprj_adr_o(mprj_adr_o), - .mprj_dat_o(mprj_dat_o), - .mprj_ack_i(mprj_ack_i), - .mprj_dat_i(mprj_dat_i), - // MGMT area R/W interface for mgmt RAM - .mgmt_ena(mgmt_ena), - .mgmt_wen_mask(mgmt_wen_mask), - .mgmt_wen(mgmt_wen), - .mgmt_addr(mgmt_addr), - .mgmt_wdata(mgmt_wdata), - .mgmt_rdata(mgmt_rdata), - // MGMT area RO interface for user RAM - .mgmt_ena_ro(mgmt_ena_ro), - .mgmt_addr_ro(mgmt_addr_ro), - .mgmt_rdata_ro(mgmt_rdata_ro) - ); - - digital_pll pll ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - `endif - .resetb(resetb), - .enable(spi_pll_ena), - .osc(clock), - .clockp({pll_clk, pll_clk90}), - .div(spi_pll_div), - .dco(spi_pll_dco_ena), - .ext_trim(spi_pll_trim) - ); - - // Housekeeping SPI (SPI slave module) - housekeeping_spi housekeeping ( - `ifdef USE_POWER_PINS - .vdd(VPWR), - .vss(VGND), - `endif - .RSTB(porb), - .SCK((hk_connect) ? mgmt_out_predata[4] : mgmt_in_data[4]), - .SDI((hk_connect) ? mgmt_out_predata[2] : mgmt_in_data[2]), - .CSB((hk_connect) ? mgmt_out_predata[3] : mgmt_in_data[3]), - .SDO(sdo_out_pre), - .sdo_enb(sdo_outenb), - .pll_dco_ena(spi_pll_dco_ena), - .pll_sel(spi_pll_sel), - .pll90_sel(spi_pll90_sel), - .pll_div(spi_pll_div), - .pll_ena(spi_pll_ena), - .pll_trim(spi_pll_trim), - .pll_bypass(ext_clk_sel), - .irq(irq_spi), - .reset(ext_reset), - .trap(trap), - .mask_rev_in(mask_rev), - .pass_thru_mgmt_reset(pass_thru_mgmt), - .pass_thru_user_reset(pass_thru_user), - .pass_thru_mgmt_sck(pass_thru_mgmt_sck), - .pass_thru_mgmt_csb(pass_thru_mgmt_csb), - .pass_thru_mgmt_sdi(pass_thru_mgmt_sdi), - .pass_thru_mgmt_sdo(pass_thru_mgmt_sdo), - .pass_thru_user_sck(pass_thru_user_sck), - .pass_thru_user_csb(pass_thru_user_csb), - .pass_thru_user_sdi(pass_thru_user_sdi), - .pass_thru_user_sdo(mgmt_in_data[11]) - ); - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/mgmt_protect.v b/caravel/rtl/mgmt_protect.v deleted file mode 100644 index e29122d..0000000 --- a/caravel/rtl/mgmt_protect.v +++ /dev/null
@@ -1,422 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -/*----------------------------------------------------------------------*/ -/* Buffers protecting the management region from the user region. */ -/* This mainly consists of tristate buffers that are enabled by a */ -/* "logic 1" output connected to the user's VCCD domain. This ensures */ -/* that the buffer is disabled and the output high-impedence when the */ -/* user 1.8V supply is absent. */ -/*----------------------------------------------------------------------*/ -/* Because there is no tristate buffer with a non-inverted enable, a */ -/* tristate inverter with non-inverted enable is used in series with */ -/* another (normal) inverter. */ -/*----------------------------------------------------------------------*/ -/* For the sake of placement/routing, one conb (logic 1) cell is used */ -/* for every buffer. */ -/*----------------------------------------------------------------------*/ - -module mgmt_protect ( -`ifdef USE_POWER_PINS - inout vccd, - inout vssd, - inout vccd1, - inout vssd1, - inout vccd2, - inout vssd2, - inout vdda1, - inout vssa1, - inout vdda2, - inout vssa2, -`endif - - input caravel_clk, - input caravel_clk2, - input caravel_rstn, - input mprj_cyc_o_core, - input mprj_stb_o_core, - input mprj_we_o_core, - input [3:0] mprj_sel_o_core, - input [31:0] mprj_adr_o_core, - input [31:0] mprj_dat_o_core, - input [2:0] user_irq_core, - - // All signal in/out directions are the reverse of the signal - // names at the buffer intrface. - - output [127:0] la_data_in_mprj, - input [127:0] la_data_out_mprj, - input [127:0] la_oenb_mprj, - input [127:0] la_iena_mprj, - - input [127:0] la_data_out_core, - output [127:0] la_data_in_core, - output [127:0] la_oenb_core, - - input [2:0] user_irq_ena, - - output user_clock, - output user_clock2, - output user_reset, - output mprj_cyc_o_user, - output mprj_stb_o_user, - output mprj_we_o_user, - output [3:0] mprj_sel_o_user, - output [31:0] mprj_adr_o_user, - output [31:0] mprj_dat_o_user, - output [2:0] user_irq, - output user1_vcc_powergood, - output user2_vcc_powergood, - output user1_vdd_powergood, - output user2_vdd_powergood -); - - wire [461:0] mprj_logic1; - wire mprj2_logic1; - - wire mprj_vdd_logic1_h; - wire mprj2_vdd_logic1_h; - wire mprj_vdd_logic1; - wire mprj2_vdd_logic1; - - wire user1_vcc_powergood; - wire user2_vcc_powergood; - wire user1_vdd_powergood; - wire user2_vdd_powergood; - - wire [127:0] la_data_in_mprj_bar; - wire [2:0] user_irq_bar; - - wire [127:0] la_data_in_enable; - wire [127:0] la_data_out_enable; - wire [2:0] user_irq_enable; - - mprj_logic_high mprj_logic_high_inst ( -`ifdef USE_POWER_PINS - .vccd1(vccd1), - .vssd1(vssd1), -`endif - .HI(mprj_logic1) - ); - - mprj2_logic_high mprj2_logic_high_inst ( -`ifdef USE_POWER_PINS - .vccd2(vccd2), - .vssd2(vssd2), -`endif - .HI(mprj2_logic1) - ); - - // Logic high in the VDDA (3.3V) domains - - mgmt_protect_hv powergood_check ( -`ifdef USE_POWER_PINS - .vccd(vccd), - .vssd(vssd), - .vdda1(vdda1), - .vssa1(vssa1), - .vdda2(vdda2), - .vssa2(vssa2), -`endif - .mprj_vdd_logic1(mprj_vdd_logic1), - .mprj2_vdd_logic1(mprj2_vdd_logic1) - ); - - // Buffering from the user side to the management side. - // NOTE: This is intended to be better protected, by a full - // chain of an lv-to-hv buffer followed by an hv-to-lv buffer. - // This serves as a placeholder until that configuration is - // checked and characterized. The function below forces the - // data input to the management core to be a solid logic 0 when - // the user project is powered down. - - sky130_fd_sc_hd__and2_1 user_to_mprj_in_ena_buf [127:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .X(la_data_in_enable), - .A(la_iena_mprj), - .B(mprj_logic1[457:330]) - ); - - sky130_fd_sc_hd__nand2_4 user_to_mprj_in_gates [127:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Y(la_data_in_mprj_bar), - .A(la_data_out_core), - .B(la_data_in_enable) - ); - - sky130_fd_sc_hd__inv_8 user_to_mprj_in_buffers [127:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Y(la_data_in_mprj), - .A(la_data_in_mprj_bar) - ); - - // Protection, similar to the above, for the three user IRQ lines - - sky130_fd_sc_hd__and2_1 user_irq_ena_buf [2:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .X(user_irq_enable), - .A(user_irq_ena), - .B(mprj_logic1[460:458]) - ); - - sky130_fd_sc_hd__nand2_4 user_irq_gates [2:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Y(user_irq_bar), - .A(user_irq_core), - .B(user_irq_enable) - ); - - sky130_fd_sc_hd__inv_8 user_irq_buffers [2:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Y(user_irq), - .A(user_irq_bar) - ); - - // The remaining circuitry guards against the management - // SoC dumping current into the user project area when - // the user project area is powered down. - - sky130_fd_sc_hd__einvp_8 mprj_rstn_buf ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(user_reset), - .A(caravel_rstn), - .TE(mprj_logic1[0]) - ); - - sky130_fd_sc_hd__einvp_8 mprj_clk_buf ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(user_clock), - .A(~caravel_clk), - .TE(mprj_logic1[1]) - ); - - sky130_fd_sc_hd__einvp_8 mprj_clk2_buf ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(user_clock2), - .A(~caravel_clk2), - .TE(mprj_logic1[2]) - ); - - sky130_fd_sc_hd__einvp_8 mprj_cyc_buf ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(mprj_cyc_o_user), - .A(~mprj_cyc_o_core), - .TE(mprj_logic1[3]) - ); - - sky130_fd_sc_hd__einvp_8 mprj_stb_buf ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(mprj_stb_o_user), - .A(~mprj_stb_o_core), - .TE(mprj_logic1[4]) - ); - - sky130_fd_sc_hd__einvp_8 mprj_we_buf ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(mprj_we_o_user), - .A(~mprj_we_o_core), - .TE(mprj_logic1[5]) - ); - - sky130_fd_sc_hd__einvp_8 mprj_sel_buf [3:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(mprj_sel_o_user), - .A(~mprj_sel_o_core), - .TE(mprj_logic1[9:6]) - ); - - sky130_fd_sc_hd__einvp_8 mprj_adr_buf [31:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(mprj_adr_o_user), - .A(~mprj_adr_o_core), - .TE(mprj_logic1[41:10]) - ); - - sky130_fd_sc_hd__einvp_8 mprj_dat_buf [31:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(mprj_dat_o_user), - .A(~mprj_dat_o_core), - .TE(mprj_logic1[73:42]) - ); - - /* Create signal to tristate the outputs to the user project */ - - sky130_fd_sc_hd__and2b_1 la_buf_enable [127:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .X(la_data_out_enable), - .A_N(la_oenb_mprj), - .B(mprj_logic1[201:74]) - ); - - /* Project data out from the managment side to the user project */ - /* area when the user project is powered down. */ - - sky130_fd_sc_hd__einvp_8 la_buf [127:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(la_data_in_core), - .A(~la_data_out_mprj), - .TE(la_data_out_enable) - ); - - /* Project data out enable (bar) from the managment side to the */ - /* user project area when the user project is powered down. */ - - sky130_fd_sc_hd__einvp_8 user_to_mprj_oen_buffers [127:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .Z(la_oenb_core), - .A(~la_oenb_mprj), - .TE(mprj_logic1[329:202]) - ); - - /* The conb cell output is a resistive connection directly to */ - /* the power supply, so when returning the user1_powergood */ - /* signal, make sure that it is buffered properly. */ - - sky130_fd_sc_hd__buf_8 mprj_pwrgood ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .A(mprj_logic1[461]), - .X(user1_vcc_powergood) - ); - - sky130_fd_sc_hd__buf_8 mprj2_pwrgood ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .A(mprj2_logic1), - .X(user2_vcc_powergood) - ); - - sky130_fd_sc_hd__buf_8 mprj_vdd_pwrgood ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .A(mprj_vdd_logic1), - .X(user1_vdd_powergood) - ); - - sky130_fd_sc_hd__buf_8 mprj2_vdd_pwrgood ( -`ifdef USE_POWER_PINS - .VPWR(vccd), - .VGND(vssd), - .VPB(vccd), - .VNB(vssd), -`endif - .A(mprj2_vdd_logic1), - .X(user2_vdd_powergood) - ); -endmodule -`default_nettype wire
diff --git a/caravel/rtl/mgmt_protect_hv.v b/caravel/rtl/mgmt_protect_hv.v deleted file mode 100644 index 23d9cf6..0000000 --- a/caravel/rtl/mgmt_protect_hv.v +++ /dev/null
@@ -1,103 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -/*----------------------------------------------------------------------*/ -/* mgmt_protect_hv: */ -/* */ -/* High voltage (3.3V) part of the mgmt_protect module. Split out into */ -/* a separate module and file so that the synthesis tools can handle it */ -/* separately from the rest, since it uses a different standard cell */ -/* library. See the file mgmt_protect.v for a full description of the */ -/* whole management protection method. */ -/*----------------------------------------------------------------------*/ - -module mgmt_protect_hv ( -`ifdef USE_POWER_PINS - inout vccd, - inout vssd, - inout vdda1, - inout vssa1, - inout vdda2, - inout vssa2, -`endif - - output mprj_vdd_logic1, - output mprj2_vdd_logic1 - -); - - wire mprj_vdd_logic1_h; - wire mprj2_vdd_logic1_h; - -`ifdef USE_POWER_PINS - // This is to emulate the substrate shorting grounds together for LVS - // purposes - assign vssa2 = vssa1; - assign vssa1 = vssd; -`endif - - // Logic high in the VDDA (3.3V) domains - - sky130_fd_sc_hvl__conb_1 mprj_logic_high_hvl ( -`ifdef USE_POWER_PINS - .VPWR(vdda1), - .VGND(vssa1), - .VPB(vdda1), - .VNB(vssa1), -`endif - .HI(mprj_vdd_logic1_h), - .LO() - ); - - sky130_fd_sc_hvl__conb_1 mprj2_logic_high_hvl ( -`ifdef USE_POWER_PINS - .VPWR(vdda2), - .VGND(vssa2), - .VPB(vdda2), - .VNB(vssa2), -`endif - .HI(mprj2_vdd_logic1_h), - .LO() - ); - - // Level shift the logic high signals into the 1.8V domain - - sky130_fd_sc_hvl__lsbufhv2lv_1 mprj_logic_high_lv ( -`ifdef USE_POWER_PINS - .VPWR(vdda1), - .VGND(vssd), - .LVPWR(vccd), - .VPB(vdda1), - .VNB(vssd), -`endif - .X(mprj_vdd_logic1), - .A(mprj_vdd_logic1_h) - ); - - sky130_fd_sc_hvl__lsbufhv2lv_1 mprj2_logic_high_lv ( -`ifdef USE_POWER_PINS - .VPWR(vdda2), - .VGND(vssd), - .LVPWR(vccd), - .VPB(vdda2), - .VNB(vssd), -`endif - .X(mprj2_vdd_logic1), - .A(mprj2_vdd_logic1_h) - ); -endmodule - -`default_nettype wire
diff --git a/caravel/rtl/mgmt_soc.v b/caravel/rtl/mgmt_soc.v deleted file mode 100644 index 2a597e0..0000000 --- a/caravel/rtl/mgmt_soc.v +++ /dev/null
@@ -1,905 +0,0 @@ -`default_nettype none -/* - * SPDX-FileCopyrightText: 2015 Clifford Wolf - * PicoSoC - A simple example SoC using PicoRV32 - * - * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Revision 1, July 2019: Added signals to drive flash_clk and flash_csb - * output enable (inverted), tied to reset so that the flash is completely - * isolated from the processor when the processor is in reset. - * - * Also: Made ram_wenb a 4-bit bus so that the memory access can be made - * byte-wide for byte-wide instructions. - * - * SPDX-License-Identifier: ISC - */ - -`ifdef PICORV32_V -`error "mgmt_soc.v must be read before picorv32.v!" -`endif - -`define PICORV32_REGS mgmt_soc_regs - -`include "picorv32.v" -`include "spimemio.v" -`include "simpleuart.v" -`include "simple_spi_master.v" -`include "counter_timer_high.v" -`include "counter_timer_low.v" -`include "wb_intercon.v" -`include "mem_wb.v" -`include "gpio_wb.v" -`include "sysctrl.v" -`include "la_wb.v" -`include "mprj_ctrl.v" -`include "convert_gpio_sigs.v" - -module mgmt_soc ( -`ifdef USE_POWER_PINS - inout vdd1v8, /* 1.8V domain */ - inout vss, -`endif - input clk, - input resetn, - - // Trap state from CPU - output trap, - - // GPIO (one pin) - output gpio_out_pad, // Connect to out on gpio pad - input gpio_in_pad, // Connect to in on gpio pad - output gpio_mode0_pad, // Connect to dm[0] on gpio pad - output gpio_mode1_pad, // Connect to dm[2] on gpio pad - output gpio_outenb_pad, // Connect to oe_n on gpio pad - output gpio_inenb_pad, // Connect to inp_dis on gpio pad - - // LA signals - input [127:0] la_input, // From User Project to cpu - output [127:0] la_output, // From CPU to User Project - output [127:0] la_oenb, // LA output enable (active low) - output [127:0] la_iena, // LA input enable (active high) - - // User Project I/O Configuration (serial load) - input mprj_vcc_pwrgood, - input mprj2_vcc_pwrgood, - input mprj_vdd_pwrgood, - input mprj2_vdd_pwrgood, - output mprj_io_loader_resetn, - output mprj_io_loader_clock, - output mprj_io_loader_data_1, - output mprj_io_loader_data_2, - - // User Project pad data (when management SoC controls the pad) - input [`MPRJ_IO_PADS-1:0] mgmt_in_data, - output [`MPRJ_IO_PADS-1:0] mgmt_out_data, - output [`MPRJ_IO_PADS-1:0] mgmt_oeb_data, - output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out, - - // IRQ - input irq_spi, // IRQ from standalone SPI - input [2:0] user_irq, // IRQ from user project - output [2:0] user_irq_ena, // enable IRQ from user project - - // Flash memory control (SPI master) - output flash_csb, - output flash_clk, - - output flash_csb_oeb, - output flash_clk_oeb, - - output flash_io0_oeb, - output flash_io1_oeb, - output flash_io2_oeb, - output flash_io3_oeb, - - output flash_csb_ieb, - output flash_clk_ieb, - - output flash_io0_ieb, - output flash_io1_ieb, - output flash_io2_ieb, - output flash_io3_ieb, - - output flash_io0_do, - output flash_io1_do, - - input flash_io0_di, - input flash_io1_di, - input flash_io2_di, - input flash_io3_di, - - // SPI pass-thru mode - input pass_thru_mgmt, - input pass_thru_mgmt_csb, - input pass_thru_mgmt_sck, - input pass_thru_mgmt_sdi, - output pass_thru_mgmt_sdo, - - // State of JTAG and SDO pins (override for management output use) - output sdo_oenb_state, - output jtag_oenb_state, - // State of flash_io2 and flash_io3 pins (override for management output use) - output flash_io2_oenb_state, - output flash_io3_oenb_state, - // SPI master->slave direct link - output hk_connect, - // User clock monitoring - input user_clk, - - // WB MI A (User project) - input mprj_ack_i, - input [31:0] mprj_dat_i, - output mprj_cyc_o, - output mprj_stb_o, - output mprj_we_o, - output [3:0] mprj_sel_o, - output [31:0] mprj_adr_o, - output [31:0] mprj_dat_o, - - // MGMT area R/W interface for mgmt RAM - output [`RAM_BLOCKS-1:0] mgmt_ena, - output [(`RAM_BLOCKS*4)-1:0] mgmt_wen_mask, - output [`RAM_BLOCKS-1:0] mgmt_wen, - output [7:0] mgmt_addr, - output [31:0] mgmt_wdata, - input [(`RAM_BLOCKS*32)-1:0] mgmt_rdata, - - // MGMT area RO interface for user RAM - output mgmt_ena_ro, - output [7:0] mgmt_addr_ro, - input [31:0] mgmt_rdata_ro -); - /* Memory reverted back to 256 words while memory has to be synthesized */ - parameter [31:0] STACKADDR = (4*(`MEM_WORDS)); // end of memory - parameter [31:0] PROGADDR_RESET = 32'h 1000_0000; - parameter [31:0] PROGADDR_IRQ = 32'h 0000_0000; - - // Slaves Base Addresses - parameter RAM_BASE_ADR = 32'h 0000_0000; - parameter STORAGE_RW_ADR = 32'h 0100_0000; - parameter STORAGE_RO_ADR = 32'h 0200_0000; - parameter FLASH_BASE_ADR = 32'h 1000_0000; - parameter UART_BASE_ADR = 32'h 2000_0000; - parameter GPIO_BASE_ADR = 32'h 2100_0000; - parameter COUNTER_TIMER0_BASE_ADR = 32'h 2200_0000; - parameter COUNTER_TIMER1_BASE_ADR = 32'h 2300_0000; - parameter SPI_MASTER_BASE_ADR = 32'h 2400_0000; - parameter LA_BASE_ADR = 32'h 2500_0000; - parameter MPRJ_CTRL_ADR = 32'h 2600_0000; - parameter FLASH_CTRL_CFG = 32'h 2D00_0000; - parameter SYS_BASE_ADR = 32'h 2F00_0000; - parameter MPRJ_BASE_ADR = 32'h 3000_0000; // WB MI A - - // UART - parameter UART_CLK_DIV = 8'h00; - parameter UART_DATA = 8'h04; - - // SPI Master - parameter SPI_MASTER_CONFIG = 8'h00; - parameter SPI_MASTER_DATA = 8'h04; - - // Counter-timer 0 - parameter COUNTER_TIMER0_CONFIG = 8'h00; - parameter COUNTER_TIMER0_VALUE = 8'h04; - parameter COUNTER_TIMER0_DATA = 8'h08; - - // Counter-timer 1 - parameter COUNTER_TIMER1_CONFIG = 8'h00; - parameter COUNTER_TIMER1_VALUE = 8'h04; - parameter COUNTER_TIMER1_DATA = 8'h08; - - // SOC GPIO - parameter GPIO_DATA = 8'h00; - parameter GPIO_ENA = 8'h04; - parameter GPIO_PU = 8'h08; - parameter GPIO_PD = 8'h0c; - - // LA - parameter LA_DATA_0 = 8'h00; - parameter LA_DATA_1 = 8'h04; - parameter LA_DATA_2 = 8'h08; - parameter LA_DATA_3 = 8'h0c; - parameter LA_OENB_0 = 8'h10; - parameter LA_OENB_1 = 8'h14; - parameter LA_OENB_2 = 8'h18; - parameter LA_OENB_3 = 8'h1c; - parameter LA_IENA_0 = 8'h20; - parameter LA_IENA_1 = 8'h24; - parameter LA_IENA_2 = 8'h28; - parameter LA_IENA_3 = 8'h2c; - parameter LA_SAMPLE = 8'h30; - - // System Control Registers - parameter PWRGOOD = 8'h00; - parameter CLK_OUT = 8'h04; - parameter TRAP_OUT = 8'h08; - parameter IRQ_SRC = 8'h0c; - - // Storage area RAM blocks - parameter [(`RAM_BLOCKS*24)-1:0] RW_BLOCKS_ADR = { - {24'h 10_0000}, - {24'h 00_0000} - }; - - parameter [23:0] RO_BLOCKS_ADR = { - {24'h 00_0000} - }; - - // Wishbone Interconnect - localparam ADR_WIDTH = 32; - localparam DAT_WIDTH = 32; - localparam NUM_SLAVES = 14; - - parameter [NUM_SLAVES*ADR_WIDTH-1: 0] ADR_MASK = { - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}}, - {8'hFF, {ADR_WIDTH-8{1'b0}}} - }; - - parameter [NUM_SLAVES*ADR_WIDTH-1: 0] SLAVE_ADR = { - {SYS_BASE_ADR}, - {FLASH_CTRL_CFG}, - {MPRJ_BASE_ADR}, - {MPRJ_CTRL_ADR}, - {LA_BASE_ADR}, - {SPI_MASTER_BASE_ADR}, - {COUNTER_TIMER1_BASE_ADR}, - {COUNTER_TIMER0_BASE_ADR}, - {GPIO_BASE_ADR}, - {UART_BASE_ADR}, - {FLASH_BASE_ADR}, - {STORAGE_RO_ADR}, - {STORAGE_RW_ADR}, - {RAM_BASE_ADR} - }; - - // The following functions are connected to specific user project - // area pins, when under control of the management area (during - // startup, and when not otherwise programmed for the user project). - - // JTAG = jtag_out (inout) - // SDO = sdo_out (output) (shared with SPI master) - // SDI = mgmt_in_data[2] (input) (shared with SPI master) - // CSB = mgmt_in_data[3] (input) (shared with SPI master) - // SCK = mgmt_in_data[4] (input) (shared with SPI master) - // ser_rx = mgmt_in_data[5] (input) - // ser_tx = mgmt_out_data[6] (output) - // irq_pin = mgmt_in_data[7] (input) - // flash_csb = mgmt_out_data[8] (output) (user area flash) - // flash_sck = mgmt_out_data[9] (output) (user area flash) - // flash_io0 = mgmt_in/out_data[10] (input) (user area flash) - // flash_io1 = mgmt_in/out_data[11] (output) (user area flash) - // irq2_pin = mgmt_in_data[12] (input) - // trap_mon = mgmt_in_data[13] (output) - // clk1_mon = mgmt_in_data[14] (output) - // clk2_mon = mgmt_in_data[15] (output) - // flash_io2 = mgmt_in_data[36] (inout) (management area flash) - // flash_io3 = mgmt_in_data[37] (inout) (management area flash) - - // OEB lines for [0] and [1] are the only ones connected directly to - // the pad. All others have OEB controlled by the configuration bit - // in the control block. - - // memory-mapped I/O control registers - wire gpio_pullup; // Intermediate GPIO pullup - wire gpio_pulldown; // Intermediate GPIO pulldown - wire gpio_outenb; // Intermediate GPIO out enable (bar) - wire gpio_out; // Intermediate GPIO output - - wire trap_output_dest; // Trap signal output destination - wire clk1_output_dest; // Core clock1 signal output destination - wire clk2_output_dest; // Core clock2 signal output destination - wire irq_7_inputsrc; // IRQ 7 source - wire irq_8_inputsrc; // IRQ 8 source - - // Convert GPIO signals to sky130_fd_io pad signals - convert_gpio_sigs convert_gpio_bit ( - .gpio_out(gpio_out), - .gpio_outenb(gpio_outenb), - .gpio_pu(gpio_pullup), - .gpio_pd(gpio_pulldown), - .gpio_out_pad(gpio_out_pad), - .gpio_outenb_pad(gpio_outenb_pad), - .gpio_inenb_pad(gpio_inenb_pad), - .gpio_mode1_pad(gpio_mode1_pad), - .gpio_mode0_pad(gpio_mode0_pad) - ); - - reg [31:0] irq; - wire irq_7; - wire irq_8; - wire irq_stall; - wire irq_uart; - wire irq_spi_master; - wire irq_counter_timer0; - wire irq_counter_timer1; - wire ser_tx; - - wire wb_clk_i; - wire wb_rst_i; - - assign irq_stall = 0; - assign irq_7 = (irq_7_inputsrc == 1'b1) ? mgmt_in_data[7] : 1'b0; - assign irq_8 = (irq_8_inputsrc == 1'b1) ? mgmt_in_data[12] : 1'b0; - - always @* begin - irq = 0; - irq[3] = irq_stall; - irq[4] = irq_uart; - irq[6] = irq_spi; - irq[7] = irq_7; - irq[8] = irq_8; - irq[9] = irq_spi_master; - irq[10] = irq_counter_timer0; - irq[11] = irq_counter_timer1; - irq[14:12] = user_irq; - end - - // Assumption : no syscon module and wb_clk is the clock coming from the - // caravel_clocking module - - assign wb_clk_i = clk; - assign wb_rst_i = ~resetn; // Redundant - - // Wishbone Master - wire [31:0] cpu_adr_o; - wire [31:0] cpu_dat_i; - wire [3:0] cpu_sel_o; - wire cpu_we_o; - wire cpu_cyc_o; - wire cpu_stb_o; - wire [31:0] cpu_dat_o; - wire cpu_ack_i; - wire mem_instr; - - picorv32_wb #( - .STACKADDR(STACKADDR), - .PROGADDR_RESET(PROGADDR_RESET), - .PROGADDR_IRQ(PROGADDR_IRQ), - .BARREL_SHIFTER(1), - .COMPRESSED_ISA(1), - .ENABLE_MUL(1), - .ENABLE_DIV(1), - .ENABLE_IRQ(1), - .ENABLE_IRQ_QREGS(0) - ) cpu ( - .wb_clk_i (wb_clk_i), - .wb_rst_i (wb_rst_i), - .trap (trap), - .irq (irq), - .mem_instr(mem_instr), - .wbm_adr_o(cpu_adr_o), - .wbm_dat_i(cpu_dat_i), - .wbm_stb_o(cpu_stb_o), - .wbm_ack_i(cpu_ack_i), - .wbm_cyc_o(cpu_cyc_o), - .wbm_dat_o(cpu_dat_o), - .wbm_we_o(cpu_we_o), - .wbm_sel_o(cpu_sel_o) - ); - - // Wishbone Slave SPIMEMIO - wire spimemio_flash_stb_i; - wire spimemio_flash_ack_o; - wire [31:0] spimemio_flash_dat_o; - - wire spimemio_cfg_stb_i; - wire spimemio_cfg_ack_o; - wire [31:0] spimemio_cfg_dat_o; - wire spimemio_quad_mode; - - wire flash_io2_do; - wire flash_io3_do; - - spimemio_wb spimemio ( - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - - // FLash Slave - .wb_flash_stb_i(spimemio_flash_stb_i), - .wb_flash_ack_o(spimemio_flash_ack_o), - .wb_flash_dat_o(spimemio_flash_dat_o), - - // Config Register Slave - .wb_cfg_stb_i(spimemio_cfg_stb_i), - .wb_cfg_ack_o(spimemio_cfg_ack_o), - .wb_cfg_dat_o(spimemio_cfg_dat_o), - - .quad_mode(spimemio_quad_mode), - .pass_thru(pass_thru_mgmt), - .pass_thru_csb(pass_thru_mgmt_csb), - .pass_thru_sck(pass_thru_mgmt_sck), - .pass_thru_sdi(pass_thru_mgmt_sdi), - .pass_thru_sdo(pass_thru_mgmt_sdo), - - .flash_csb (flash_csb), - .flash_clk (flash_clk), - - .flash_csb_oeb (flash_csb_oeb), - .flash_clk_oeb (flash_clk_oeb), - - .flash_io0_oeb (flash_io0_oeb), - .flash_io1_oeb (flash_io1_oeb), - .flash_io2_oeb (flash_io2_oeb), // through GPIO 36 - .flash_io3_oeb (flash_io3_oeb), // through GPIO 37 - - .flash_csb_ieb (flash_csb_ieb), - .flash_clk_ieb (flash_clk_ieb), - - .flash_io0_ieb (flash_io0_ieb), - .flash_io1_ieb (flash_io1_ieb), - .flash_io2_ieb (), // unused - .flash_io3_ieb (), // unused - - .flash_io0_do (flash_io0_do), - .flash_io1_do (flash_io1_do), - .flash_io2_do (flash_io2_do), // through GPIO 36 - .flash_io3_do (flash_io3_do), // through GPIO 37 - - .flash_io0_di (flash_io0_di), - .flash_io1_di (flash_io1_di), - .flash_io2_di (mgmt_in_data[(`MPRJ_IO_PADS)-2]), - .flash_io3_di (mgmt_in_data[(`MPRJ_IO_PADS)-1]) - ); - - // Wishbone Slave uart - wire uart_stb_i; - wire uart_ack_o; - wire [31:0] uart_dat_o; - wire uart_enabled; - - simpleuart_wb #( - .BASE_ADR(UART_BASE_ADR), - .CLK_DIV(UART_CLK_DIV), - .DATA(UART_DATA) - ) simpleuart ( - // Wishbone Interface - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - - .wb_stb_i(uart_stb_i), - .wb_ack_o(uart_ack_o), - .wb_dat_o(uart_dat_o), - - .uart_enabled(uart_enabled), - .ser_tx(ser_tx), - .ser_rx(mgmt_in_data[5]) - ); - - // Wishbone SPI master - wire spi_master_stb_i; - wire spi_master_ack_o; - wire [31:0] spi_master_dat_o; - wire spi_enabled; - wire spi_csb, spi_sck, spi_sdo; - - simple_spi_master_wb #( - .BASE_ADR(SPI_MASTER_BASE_ADR), - .CONFIG(SPI_MASTER_CONFIG), - .DATA(SPI_MASTER_DATA) - ) simple_spi_master_inst ( - // Wishbone Interface - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - - .wb_stb_i(spi_master_stb_i), - .wb_ack_o(spi_master_ack_o), - .wb_dat_o(spi_master_dat_o), - - .hk_connect(hk_connect), - .spi_enabled(spi_enabled), - .csb(spi_csb), - .sck(spi_sck), - .sdo(spi_sdo), - .sdi(mgmt_in_data[1]), - .sdoenb(), - .irq(irq_spi_master) - ); - - wire counter_timer_strobe, counter_timer_offset; - wire counter_timer0_enable, counter_timer1_enable; - wire counter_timer0_stop, counter_timer1_stop; - - // Wishbone Counter-timer 0 - wire counter_timer0_stb_i; - wire counter_timer0_ack_o; - wire [31:0] counter_timer0_dat_o; - - counter_timer_low_wb #( - .BASE_ADR(COUNTER_TIMER0_BASE_ADR), - .CONFIG(COUNTER_TIMER0_CONFIG), - .VALUE(COUNTER_TIMER0_VALUE), - .DATA(COUNTER_TIMER0_DATA) - ) counter_timer_0 ( - // Wishbone Interface - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - - .wb_stb_i(counter_timer0_stb_i), - .wb_ack_o(counter_timer0_ack_o), - .wb_dat_o(counter_timer0_dat_o), - - .enable_in(counter_timer1_enable), - .stop_in(counter_timer1_stop), - .strobe(counter_timer_strobe), - .is_offset(counter_timer_offset), - .enable_out(counter_timer0_enable), - .stop_out(counter_timer0_stop), - .irq(irq_counter_timer0) - ); - - // Wishbone Counter-timer 1 - wire counter_timer1_stb_i; - wire counter_timer1_ack_o; - wire [31:0] counter_timer1_dat_o; - - counter_timer_high_wb #( - .BASE_ADR(COUNTER_TIMER1_BASE_ADR), - .CONFIG(COUNTER_TIMER1_CONFIG), - .VALUE(COUNTER_TIMER1_VALUE), - .DATA(COUNTER_TIMER1_DATA) - ) counter_timer_1 ( - // Wishbone Interface - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - - .wb_stb_i(counter_timer1_stb_i), - .wb_ack_o(counter_timer1_ack_o), - .wb_dat_o(counter_timer1_dat_o), - - .enable_in(counter_timer0_enable), - .strobe(counter_timer_strobe), - .stop_in(counter_timer0_stop), - .is_offset(counter_timer_offset), - .enable_out(counter_timer1_enable), - .stop_out(counter_timer1_stop), - .irq(irq_counter_timer1) - ); - - // Wishbone Slave GPIO Registers - wire gpio_stb_i; - wire gpio_ack_o; - wire [31:0] gpio_dat_o; - - gpio_wb #( - .BASE_ADR(GPIO_BASE_ADR), - .GPIO_DATA(GPIO_DATA), - .GPIO_ENA(GPIO_ENA), - .GPIO_PD(GPIO_PD), - .GPIO_PU(GPIO_PU) - ) gpio_wb ( - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - .wb_stb_i(gpio_stb_i), - .wb_ack_o(gpio_ack_o), - .wb_dat_o(gpio_dat_o), - .gpio_in_pad(gpio_in_pad), - .gpio(gpio_out), - .gpio_oeb(gpio_outenb), - .gpio_pu(gpio_pullup), - .gpio_pd(gpio_pulldown) - ); - - // Wishbone Slave System Control Register - wire sys_stb_i; - wire sys_ack_o; - wire [31:0] sys_dat_o; - - sysctrl_wb #( - .BASE_ADR(SYS_BASE_ADR), - .PWRGOOD(PWRGOOD), - .CLK_OUT(CLK_OUT), - .TRAP_OUT(TRAP_OUT), - .IRQ_SRC(IRQ_SRC) - ) sysctrl ( - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - - .wb_stb_i(sys_stb_i), - .wb_ack_o(sys_ack_o), - .wb_dat_o(sys_dat_o), - - .usr1_vcc_pwrgood(mprj_vcc_pwrgood), - .usr2_vcc_pwrgood(mprj2_vcc_pwrgood), - .usr1_vdd_pwrgood(mprj_vdd_pwrgood), - .usr2_vdd_pwrgood(mprj2_vdd_pwrgood), - .trap_output_dest(trap_output_dest), - .clk1_output_dest(clk1_output_dest), - .clk2_output_dest(clk2_output_dest), - .irq_7_inputsrc(irq_7_inputsrc), - .irq_8_inputsrc(irq_8_inputsrc) - ); - - // Logic Analyzer - wire la_stb_i; - wire la_ack_o; - wire [31:0] la_dat_o; - - la_wb #( - .BASE_ADR(LA_BASE_ADR), - .LA_DATA_0(LA_DATA_0), - .LA_DATA_1(LA_DATA_1), - .LA_DATA_3(LA_DATA_3), - .LA_OENB_0(LA_OENB_0), - .LA_OENB_1(LA_OENB_1), - .LA_OENB_2(LA_OENB_2), - .LA_OENB_3(LA_OENB_3), - .LA_IENA_0(LA_IENA_0), - .LA_IENA_1(LA_IENA_1), - .LA_IENA_2(LA_IENA_2), - .LA_IENA_3(LA_IENA_3), - .LA_SAMPLE(LA_SAMPLE) - ) la ( - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - - .wb_stb_i(la_stb_i), - .wb_ack_o(la_ack_o), - .wb_dat_o(la_dat_o), - - .la_data(la_output), - .la_data_in(la_input), - .la_oenb(la_oenb), - .la_iena(la_iena) - ); - - // User project WB MI A port - assign mprj_cyc_o = cpu_cyc_o; - assign mprj_we_o = cpu_we_o; - assign mprj_sel_o = cpu_sel_o; - assign mprj_adr_o = cpu_adr_o; - assign mprj_dat_o = cpu_dat_o; - - // WB Slave User Project Control - wire mprj_ctrl_stb_i; - wire mprj_ctrl_ack_o; - wire [31:0] mprj_ctrl_dat_o; - wire [`MPRJ_IO_PADS-1:0] mgmt_out_pre; - - // Bits assigned to specific functions as outputs prevent the mprj - // GPIO-as-output from applying data when that function is active - - assign mgmt_out_data[`MPRJ_IO_PADS-3:16] = mgmt_out_pre[`MPRJ_IO_PADS-3:16]; - - // spimemio module controls last two data out lines when in quad mode. - // These go to GPIO 36 and 37. The input and OEB lines are routed - // individually and have their own independent signal names. - - assign mgmt_out_data[`MPRJ_IO_PADS-1] = (spimemio_quad_mode) ? - flash_io3_do : mgmt_out_pre[`MPRJ_IO_PADS-1]; - assign mgmt_out_data[`MPRJ_IO_PADS-2] = (spimemio_quad_mode) ? - flash_io2_do : mgmt_out_pre[`MPRJ_IO_PADS-2]; - - // Routing of output monitors (PLL, trap, clk1, clk2) - assign mgmt_out_data[15] = clk2_output_dest ? user_clk : mgmt_out_pre[15]; - assign mgmt_out_data[14] = clk1_output_dest ? clk : mgmt_out_pre[14]; - assign mgmt_out_data[13] = trap_output_dest ? trap : mgmt_out_pre[13]; - - assign mgmt_out_data[12:7] = mgmt_out_pre[12:7]; - assign mgmt_out_data[6] = uart_enabled ? ser_tx : mgmt_out_pre[6]; - - assign mgmt_out_data[0] = mgmt_out_pre[0]; - assign mgmt_out_data[1] = mgmt_out_pre[1]; - assign mgmt_out_data[5] = mgmt_out_pre[5]; - - assign mgmt_out_data[2] = spi_enabled ? spi_sdo : mgmt_out_pre[2]; - assign mgmt_out_data[3] = spi_enabled ? spi_csb : mgmt_out_pre[3]; - assign mgmt_out_data[4] = spi_enabled ? spi_sck : mgmt_out_pre[4]; - - mprj_ctrl_wb #( - .BASE_ADR(MPRJ_CTRL_ADR) - ) mprj_ctrl ( - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - .wb_stb_i(mprj_ctrl_stb_i), - .wb_ack_o(mprj_ctrl_ack_o), - .wb_dat_o(mprj_ctrl_dat_o), - - .serial_clock(mprj_io_loader_clock), - .serial_resetn(mprj_io_loader_resetn), - .serial_data_out_1(mprj_io_loader_data_1), - .serial_data_out_2(mprj_io_loader_data_2), - .sdo_oenb_state(sdo_oenb_state), - .jtag_oenb_state(jtag_oenb_state), - .flash_io2_oenb_state(flash_io2_oenb_state), - .flash_io3_oenb_state(flash_io3_oenb_state), - .mgmt_gpio_out(mgmt_out_pre), - .mgmt_gpio_oeb(mgmt_oeb_data), - .mgmt_gpio_in(mgmt_in_data), - .pwr_ctrl_out(pwr_ctrl_out), - .user_irq_ena(user_irq_ena) - ); - - // Wishbone Slave RAM - wire mem_stb_i; - wire mem_ack_o; - wire [31:0] mem_dat_o; - - mem_wb soc_mem ( - `ifdef USE_POWER_PINS - .VPWR(vdd1v8), - .VGND(vss), - `endif - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - - .wb_stb_i(mem_stb_i), - .wb_ack_o(mem_ack_o), - .wb_dat_o(mem_dat_o) - ); - - wire stg_rw_stb_i; - wire stg_ro_stb_i; - wire stg_rw_ack_o; - wire stg_ro_ack_o; - wire [31:0] stg_rw_dat_o; - wire [31:0] stg_ro_dat_o; - - // Storage area wishbone brige - storage_bridge_wb #( - .RW_BLOCKS_ADR(RW_BLOCKS_ADR), - .RO_BLOCKS_ADR(RO_BLOCKS_ADR) - ) wb_bridge ( - .wb_clk_i(wb_clk_i), - .wb_rst_i(wb_rst_i), - .wb_adr_i(cpu_adr_o), - .wb_dat_i(cpu_dat_o), - .wb_sel_i(cpu_sel_o), - .wb_we_i(cpu_we_o), - .wb_cyc_i(cpu_cyc_o), - .wb_stb_i({stg_ro_stb_i, stg_rw_stb_i}), - .wb_ack_o({stg_ro_ack_o, stg_rw_ack_o}), - .wb_rw_dat_o(stg_rw_dat_o), - // MGMT_AREA RO WB Interface - .wb_ro_dat_o(stg_ro_dat_o), - // MGMT Area native memory interface - .mgmt_ena(mgmt_ena), - .mgmt_wen_mask(mgmt_wen_mask), - .mgmt_wen(mgmt_wen), - .mgmt_addr(mgmt_addr), - .mgmt_wdata(mgmt_wdata), - .mgmt_rdata(mgmt_rdata), - // MGMT_AREA RO interface - .mgmt_ena_ro(mgmt_ena_ro), - .mgmt_addr_ro(mgmt_addr_ro), - .mgmt_rdata_ro(mgmt_rdata_ro) - ); - - // Wishbone intercon logic - wb_intercon #( - .AW(ADR_WIDTH), - .DW(DAT_WIDTH), - .NS(NUM_SLAVES), - .ADR_MASK(ADR_MASK), - .SLAVE_ADR(SLAVE_ADR) - ) intercon ( - // Master Interface - .wbm_adr_i(cpu_adr_o), - .wbm_stb_i(cpu_stb_o), - .wbm_dat_o(cpu_dat_i), - .wbm_ack_o(cpu_ack_i), - - // Slaves Interface - .wbs_stb_o({ sys_stb_i, spimemio_cfg_stb_i, - mprj_stb_o, mprj_ctrl_stb_i, la_stb_i, - spi_master_stb_i, counter_timer1_stb_i, counter_timer0_stb_i, - gpio_stb_i, uart_stb_i, - spimemio_flash_stb_i, stg_ro_stb_i, stg_rw_stb_i, mem_stb_i }), - .wbs_dat_i({ sys_dat_o, spimemio_cfg_dat_o, - mprj_dat_i, mprj_ctrl_dat_o, la_dat_o, - spi_master_dat_o, counter_timer1_dat_o, counter_timer0_dat_o, - gpio_dat_o, uart_dat_o, - spimemio_flash_dat_o, stg_ro_dat_o ,stg_rw_dat_o, mem_dat_o }), - .wbs_ack_i({ sys_ack_o, spimemio_cfg_ack_o, - mprj_ack_i, mprj_ctrl_ack_o, la_ack_o, - spi_master_ack_o, counter_timer1_ack_o, counter_timer0_ack_o, - gpio_ack_o, uart_ack_o, - spimemio_flash_ack_o, stg_ro_ack_o, stg_rw_ack_o, mem_ack_o }) - ); - -endmodule - -// Implementation note: -// Replace the following two modules with wrappers for your SRAM cells. - -module mgmt_soc_regs ( - input clk, wen, - input [5:0] waddr, - input [5:0] raddr1, - input [5:0] raddr2, - input [31:0] wdata, - output [31:0] rdata1, - output [31:0] rdata2 -); - reg [31:0] regs [0:31]; - - always @(posedge clk) - if (wen) regs[waddr[4:0]] <= wdata; - - assign rdata1 = regs[raddr1[4:0]]; - assign rdata2 = regs[raddr2[4:0]]; -endmodule -`default_nettype wire
diff --git a/caravel/rtl/mprj2_logic_high.v b/caravel/rtl/mprj2_logic_high.v deleted file mode 100644 index e63b1a4..0000000 --- a/caravel/rtl/mprj2_logic_high.v +++ /dev/null
@@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -module mprj2_logic_high ( -`ifdef USE_POWER_PINS - inout vccd2, - inout vssd2, -`endif - output HI -); -sky130_fd_sc_hd__conb_1 inst ( -`ifdef USE_POWER_PINS - .VPWR(vccd2), - .VGND(vssd2), - .VPB(vccd2), - .VNB(vssd2), -`endif - .HI(HI), - .LO() - ); -endmodule
diff --git a/caravel/rtl/mprj_ctrl.v b/caravel/rtl/mprj_ctrl.v deleted file mode 100644 index f6dbfd3..0000000 --- a/caravel/rtl/mprj_ctrl.v +++ /dev/null
@@ -1,437 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -module mprj_ctrl_wb #( - parameter BASE_ADR = 32'h 2300_0000, - parameter XFER = 8'h 00, - parameter PWRDATA = 8'h 04, - parameter IRQDATA = 8'h 08, - parameter IODATA = 8'h 0c, // One word per 32 IOs - parameter IOCONFIG = 8'h 24 -)( - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_dat_i, - input [31:0] wb_adr_i, - input [3:0] wb_sel_i, - input wb_cyc_i, - input wb_stb_i, - input wb_we_i, - - output [31:0] wb_dat_o, - output wb_ack_o, - - // Output is to serial loader - output serial_clock, - output serial_resetn, - output serial_data_out_1, - output serial_data_out_2, - - // Pass state of OEB bit on SDO and JTAG back to the core - // so that the function can be overridden for management output - output sdo_oenb_state, - output jtag_oenb_state, - output flash_io2_oenb_state, - output flash_io3_oenb_state, - - // Read/write data to each GPIO pad from management SoC - input [`MPRJ_IO_PADS-1:0] mgmt_gpio_in, - output [`MPRJ_IO_PADS-1:0] mgmt_gpio_out, - output [`MPRJ_IO_PADS-1:0] mgmt_gpio_oeb, - - // Write data to power controls - output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out, - - // Enable user project IRQ signals to management SoC - output [2:0] user_irq_ena -); - wire resetn; - wire valid; - wire ready; - wire [3:0] iomem_we; - - assign resetn = ~wb_rst_i; - assign valid = wb_stb_i && wb_cyc_i; - - assign iomem_we = wb_sel_i & {4{wb_we_i}}; - assign wb_ack_o = ready; - - mprj_ctrl #( - .BASE_ADR(BASE_ADR), - .XFER(XFER), - .PWRDATA(PWRDATA), - .IRQDATA(IRQDATA), - .IODATA(IODATA), - .IOCONFIG(IOCONFIG) - ) mprj_ctrl ( - .clk(wb_clk_i), - .resetn(resetn), - .iomem_addr(wb_adr_i), - .iomem_valid(valid), - .iomem_wstrb(iomem_we[1:0]), - .iomem_wdata(wb_dat_i), - .iomem_rdata(wb_dat_o), - .iomem_ready(ready), - - .serial_clock(serial_clock), - .serial_resetn(serial_resetn), - .serial_data_out_1(serial_data_out_1), - .serial_data_out_2(serial_data_out_2), - .sdo_oenb_state(sdo_oenb_state), - .jtag_oenb_state(jtag_oenb_state), - .flash_io2_oenb_state(flash_io2_oenb_state), - .flash_io3_oenb_state(flash_io3_oenb_state), - // .mgmt_gpio_io(mgmt_gpio_io) - .mgmt_gpio_in(mgmt_gpio_in), - .mgmt_gpio_out(mgmt_gpio_out), - .mgmt_gpio_oeb(mgmt_gpio_oeb), - - // Write data to power controls - .pwr_ctrl_out(pwr_ctrl_out), - // Enable user project IRQ signals to management SoC - .user_irq_ena(user_irq_ena) - ); - -endmodule - -module mprj_ctrl #( - parameter BASE_ADR = 32'h 2300_0000, - parameter XFER = 8'h 00, - parameter PWRDATA = 8'h 04, - parameter IRQDATA = 8'h 08, - parameter IODATA = 8'h 0c, - parameter IOCONFIG = 8'h 24, - parameter IO_CTRL_BITS = 13 -)( - input clk, - input resetn, - - input [31:0] iomem_addr, - input iomem_valid, - input [1:0] iomem_wstrb, - input [31:0] iomem_wdata, - output reg [31:0] iomem_rdata, - output reg iomem_ready, - - output serial_clock, - output serial_resetn, - output serial_data_out_1, - output serial_data_out_2, - output sdo_oenb_state, - output jtag_oenb_state, - output flash_io2_oenb_state, - output flash_io3_oenb_state, - input [`MPRJ_IO_PADS-1:0] mgmt_gpio_in, - output [`MPRJ_IO_PADS-1:0] mgmt_gpio_out, - output [`MPRJ_IO_PADS-1:0] mgmt_gpio_oeb, - output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out, - output [2:0] user_irq_ena -); - -`define IDLE 2'b00 -`define START 2'b01 -`define XBYTE 2'b10 -`define LOAD 2'b11 - - localparam IO_WORDS = (`MPRJ_IO_PADS % 32 != 0) + (`MPRJ_IO_PADS / 32); - - localparam IO_BASE_ADR = (BASE_ADR | IOCONFIG); - - localparam OEB = 1; // Offset of output enable in shift register. - localparam INP_DIS = 3; // Offset of input disable in shift register. - - reg [IO_CTRL_BITS-1:0] io_ctrl[`MPRJ_IO_PADS-1:0]; // I/O control, 1 word per gpio pad - reg [`MPRJ_IO_PADS-1:0] mgmt_gpio_out; // I/O write data, 1 bit per gpio pad - reg [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out; // Power write data, 1 bit per power pad - reg [2:0] user_irq_ena; // Enable user to raise IRQs - reg xfer_ctrl; // Transfer control (1 bit) - - wire [IO_WORDS-1:0] io_data_sel; // wishbone selects - wire pwr_data_sel; - wire irq_data_sel; - wire xfer_sel; - wire busy; - wire selected; - wire [`MPRJ_IO_PADS-1:0] io_ctrl_sel; - reg [31:0] iomem_rdata_pre; - - wire [`MPRJ_IO_PADS-1:0] mgmt_gpio_in; - - wire sdo_oenb_state, jtag_oenb_state; - wire flash_io2_oenb_state, flash_io3_oenb_state; - - // JTAG and housekeeping SDO are normally controlled by their respective - // modules with OEB set to the default 1 value. If configured for an - // additional output by setting the OEB bit low, then pass this information - // back to the core so that the default signals can be overridden. - - assign jtag_oenb_state = io_ctrl[0][OEB]; - assign sdo_oenb_state = io_ctrl[1][OEB]; - - // Likewise for the flash_io2 and flash_io3, although they are configured - // as input by default. - assign flash_io2_oenb_state = io_ctrl[(`MPRJ_IO_PADS)-2][OEB]; - assign flash_io3_oenb_state = io_ctrl[(`MPRJ_IO_PADS)-1][OEB]; - - `define wtop (((i+1)*32 > `MPRJ_IO_PADS) ? `MPRJ_IO_PADS-1 : (i+1)*32-1) - `define wbot (i*32) - `define rtop (`wtop - `wbot) - - genvar i; - - // Assign selection bits per address - - assign xfer_sel = (iomem_addr[7:0] == XFER); - assign pwr_data_sel = (iomem_addr[7:0] == PWRDATA); - assign irq_data_sel = (iomem_addr[7:0] == IRQDATA); - - generate - for (i=0; i<IO_WORDS; i=i+1) begin - assign io_data_sel[i] = (iomem_addr[7:0] == (IODATA + i*4)); - end - - for (i=0; i<`MPRJ_IO_PADS; i=i+1) begin - assign io_ctrl_sel[i] = (iomem_addr[7:0] == (IO_BASE_ADR[7:0] + i*4)); - assign mgmt_gpio_oeb[i] = ~io_ctrl[i][INP_DIS]; - end - endgenerate - - - // Set selection and iomem_rdata_pre - - assign selected = xfer_sel || pwr_data_sel || irq_data_sel || (|io_data_sel) || (|io_ctrl_sel); - - wire [31:0] io_data_arr[0:IO_WORDS-1]; - wire [31:0] io_ctrl_arr[0:`MPRJ_IO_PADS-1]; - generate - for (i=0; i<IO_WORDS; i=i+1) begin - assign io_data_arr[i] = {{(31-`rtop){1'b0}}, mgmt_gpio_in[`wtop:`wbot]}; - - end - for (i=0; i<`MPRJ_IO_PADS; i=i+1) begin - assign io_ctrl_arr[i] = {{(32-IO_CTRL_BITS){1'b0}}, io_ctrl[i]}; - end - endgenerate - - - integer j; - always @ * begin - iomem_rdata_pre = 'b0; - if (xfer_sel) begin - iomem_rdata_pre = {31'b0, busy}; - end else if (pwr_data_sel) begin - iomem_rdata_pre = {{(32-`MPRJ_PWR_PADS){1'b0}}, pwr_ctrl_out}; - end else if (irq_data_sel) begin - iomem_rdata_pre = {29'b0, user_irq_ena}; - end else if (|io_data_sel) begin - for (j=0; j<IO_WORDS; j=j+1) begin - if (io_data_sel[j]) begin - iomem_rdata_pre = io_data_arr[j]; - end - end - end else begin - for (j=0; j<`MPRJ_IO_PADS; j=j+1) begin - if (io_ctrl_sel[j]) begin - iomem_rdata_pre = io_ctrl_arr[j]; - end - end - end - end - - // General I/O transfer - - always @(posedge clk) begin - if (!resetn) begin - iomem_rdata <= 0; - iomem_ready <= 0; - end else begin - iomem_ready <= 0; - if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin - iomem_ready <= 1'b 1; - - if (selected) begin - iomem_rdata <= iomem_rdata_pre; - end - end - end - end - - // I/O write of xfer bit. Also handles iomem_ready signal and power data. - - always @(posedge clk) begin - if (!resetn) begin - xfer_ctrl <= 0; - pwr_ctrl_out <= 0; - user_irq_ena <= 0; - end else begin - if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin - if (xfer_sel) begin - if (iomem_wstrb[0]) xfer_ctrl <= iomem_wdata[0]; - end else if (pwr_data_sel) begin - if (iomem_wstrb[0]) pwr_ctrl_out <= iomem_wdata[`MPRJ_PWR_PADS-1:0]; - end else if (irq_data_sel) begin - if (iomem_wstrb[0]) user_irq_ena <= iomem_wdata[2:0]; - end - end else begin - xfer_ctrl <= 1'b0; // Immediately self-resetting - end - end - end - - // I/O transfer of gpio data to/from user project region under management - // SoC control - - generate - for (i=0; i<IO_WORDS; i=i+1) begin - always @(posedge clk) begin - if (!resetn) begin - mgmt_gpio_out[`wtop:`wbot] <= 'd0; - end else begin - if (iomem_valid && !iomem_ready && iomem_addr[31:8] == - BASE_ADR[31:8]) begin - if (io_data_sel[i]) begin - if (iomem_wstrb[0]) begin - mgmt_gpio_out[`wtop:`wbot] <= iomem_wdata[`rtop:0]; - end - end - end - end - end - end - - for (i=0; i<`MPRJ_IO_PADS; i=i+1) begin - always @(posedge clk) begin - if (!resetn) begin - // NOTE: This initialization must match the defaults passed - // to the control blocks. Specifically, 0x1803 is for a - // bidirectional pad, and 0x0403 is for a simple input pad - if ((i < 2) || (i >= `MPRJ_IO_PADS - 2)) begin - io_ctrl[i] <= 'h1803; - end else begin - io_ctrl[i] <= 'h0403; - end - end else begin - if (iomem_valid && !iomem_ready && - iomem_addr[31:8] == BASE_ADR[31:8]) begin - if (io_ctrl_sel[i]) begin - // NOTE: Byte-wide write to io_ctrl is prohibited - if (iomem_wstrb[0]) - io_ctrl[i] <= iomem_wdata[IO_CTRL_BITS-1:0]; - end - end - end - end - end - endgenerate - - reg [3:0] xfer_count; - reg [4:0] pad_count_1; - reg [5:0] pad_count_2; - reg [1:0] xfer_state; - reg serial_clock; - reg serial_resetn; - - reg [IO_CTRL_BITS-1:0] serial_data_staging_1; - reg [IO_CTRL_BITS-1:0] serial_data_staging_2; - - wire serial_data_out_1; - wire serial_data_out_2; - - assign serial_data_out_1 = serial_data_staging_1[IO_CTRL_BITS-1]; - assign serial_data_out_2 = serial_data_staging_2[IO_CTRL_BITS-1]; - assign busy = (xfer_state != `IDLE); - - always @(posedge clk or negedge resetn) begin - if (resetn == 1'b0) begin - - xfer_state <= `IDLE; - xfer_count <= 4'd0; - /* NOTE: This assumes that MPRJ_IO_PADS_1 and MPRJ_IO_PADS_2 are - * equal, because they get clocked the same number of cycles by - * the same clock signal. pad_count_2 gates the count for both. - */ - pad_count_1 <= `MPRJ_IO_PADS_1 - 1; - pad_count_2 <= `MPRJ_IO_PADS_1; - serial_resetn <= 1'b0; - serial_clock <= 1'b0; - serial_data_staging_1 <= 0; - serial_data_staging_2 <= 0; - - end else begin - - if (xfer_state == `IDLE) begin - pad_count_1 <= `MPRJ_IO_PADS_1 - 1; - pad_count_2 <= `MPRJ_IO_PADS_1; - serial_resetn <= 1'b1; - serial_clock <= 1'b0; - if (xfer_ctrl == 1'b1) begin - xfer_state <= `START; - end - end else if (xfer_state == `START) begin - serial_resetn <= 1'b1; - serial_clock <= 1'b0; - xfer_count <= 6'd0; - pad_count_1 <= pad_count_1 - 1; - pad_count_2 <= pad_count_2 + 1; - xfer_state <= `XBYTE; - serial_data_staging_1 <= io_ctrl[pad_count_1]; - serial_data_staging_2 <= io_ctrl[pad_count_2]; - end else if (xfer_state == `XBYTE) begin - serial_resetn <= 1'b1; - serial_clock <= ~serial_clock; - if (serial_clock == 1'b0) begin - if (xfer_count == IO_CTRL_BITS - 1) begin - if (pad_count_2 == `MPRJ_IO_PADS) begin - xfer_state <= `LOAD; - end else begin - xfer_state <= `START; - end - end else begin - xfer_count <= xfer_count + 1; - end - end else begin - serial_data_staging_1 <= {serial_data_staging_1[IO_CTRL_BITS-2:0], 1'b0}; - serial_data_staging_2 <= {serial_data_staging_2[IO_CTRL_BITS-2:0], 1'b0}; - end - end else if (xfer_state == `LOAD) begin - xfer_count <= xfer_count + 1; - - /* Load sequence: Raise clock for final data shift in; - * Pulse reset low while clock is high - * Set clock back to zero. - * Return to idle mode. - */ - if (xfer_count == 4'd0) begin - serial_clock <= 1'b1; - serial_resetn <= 1'b1; - end else if (xfer_count == 4'd1) begin - serial_clock <= 1'b1; - serial_resetn <= 1'b0; - end else if (xfer_count == 4'd2) begin - serial_clock <= 1'b1; - serial_resetn <= 1'b1; - end else if (xfer_count == 4'd3) begin - serial_resetn <= 1'b1; - serial_clock <= 1'b0; - xfer_state <= `IDLE; - end - end - end - end - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/mprj_io.v b/caravel/rtl/mprj_io.v deleted file mode 100644 index 3a94da0..0000000 --- a/caravel/rtl/mprj_io.v +++ /dev/null
@@ -1,138 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -// `default_nettype none - -/* Define the array of GPIO pads. Note that the analog project support - * version of caravel (caravan) defines fewer GPIO and replaces them - * with analog in the chip_io_alt module. Because the pad signalling - * remains the same, `MPRJ_IO_PADS does not change, so a local parameter - * is made that can be made smaller than `MPRJ_IO_PADS to accommodate - * the analog pads. - */ - -module mprj_io #( - parameter AREA1PADS = `MPRJ_IO_PADS_1, - parameter TOTAL_PADS = `MPRJ_IO_PADS -) ( - inout vddio, - inout vssio, - inout vdda, - inout vssa, - inout vccd, - inout vssd, - - inout vdda1, - inout vdda2, - inout vssa1, - inout vssa2, - inout vccd1, - inout vccd2, - inout vssd1, - inout vssd2, - - input vddio_q, - input vssio_q, - input analog_a, - input analog_b, - input porb_h, - inout [TOTAL_PADS-1:0] io, - input [TOTAL_PADS-1:0] io_out, - input [TOTAL_PADS-1:0] oeb, - input [TOTAL_PADS-1:0] hldh_n, - input [TOTAL_PADS-1:0] enh, - input [TOTAL_PADS-1:0] inp_dis, - input [TOTAL_PADS-1:0] ib_mode_sel, - input [TOTAL_PADS-1:0] vtrip_sel, - input [TOTAL_PADS-1:0] slow_sel, - input [TOTAL_PADS-1:0] holdover, - input [TOTAL_PADS-1:0] analog_en, - input [TOTAL_PADS-1:0] analog_sel, - input [TOTAL_PADS-1:0] analog_pol, - input [TOTAL_PADS*3-1:0] dm, - output [TOTAL_PADS-1:0] io_in, - output [TOTAL_PADS-1:0] io_in_3v3, - inout [TOTAL_PADS-10:0] analog_io, - inout [TOTAL_PADS-10:0] analog_noesd_io -); - - wire [TOTAL_PADS-1:0] loop1_io; - wire [6:0] no_connect_1a, no_connect_1b; - wire [1:0] no_connect_2a, no_connect_2b; - - sky130_ef_io__gpiov2_pad_wrapped area1_io_pad [AREA1PADS - 1:0] ( - `USER1_ABUTMENT_PINS - `ifndef TOP_ROUTING - ,.PAD(io[AREA1PADS - 1:0]), - `endif - .OUT(io_out[AREA1PADS - 1:0]), - .OE_N(oeb[AREA1PADS - 1:0]), - .HLD_H_N(hldh_n[AREA1PADS - 1:0]), - .ENABLE_H(enh[AREA1PADS - 1:0]), - .ENABLE_INP_H(loop1_io[AREA1PADS - 1:0]), - .ENABLE_VDDA_H(porb_h), - .ENABLE_VSWITCH_H(vssio), - .ENABLE_VDDIO(vccd), - .INP_DIS(inp_dis[AREA1PADS - 1:0]), - .IB_MODE_SEL(ib_mode_sel[AREA1PADS - 1:0]), - .VTRIP_SEL(vtrip_sel[AREA1PADS - 1:0]), - .SLOW(slow_sel[AREA1PADS - 1:0]), - .HLD_OVR(holdover[AREA1PADS - 1:0]), - .ANALOG_EN(analog_en[AREA1PADS - 1:0]), - .ANALOG_SEL(analog_sel[AREA1PADS - 1:0]), - .ANALOG_POL(analog_pol[AREA1PADS - 1:0]), - .DM(dm[AREA1PADS*3 - 1:0]), - .PAD_A_NOESD_H({analog_noesd_io[AREA1PADS - 8:0], no_connect_1a}), - .PAD_A_ESD_0_H({analog_io[AREA1PADS - 8:0], no_connect_1b}), - .PAD_A_ESD_1_H(), - .IN(io_in[AREA1PADS - 1:0]), - .IN_H(io_in_3v3[AREA1PADS - 1:0]), - .TIE_HI_ESD(), - .TIE_LO_ESD(loop1_io[AREA1PADS - 1:0]) - ); - - sky130_ef_io__gpiov2_pad_wrapped area2_io_pad [TOTAL_PADS - AREA1PADS - 1:0] ( - `USER2_ABUTMENT_PINS - `ifndef TOP_ROUTING - ,.PAD(io[TOTAL_PADS - 1:AREA1PADS]), - `endif - .OUT(io_out[TOTAL_PADS - 1:AREA1PADS]), - .OE_N(oeb[TOTAL_PADS - 1:AREA1PADS]), - .HLD_H_N(hldh_n[TOTAL_PADS - 1:AREA1PADS]), - .ENABLE_H(enh[TOTAL_PADS - 1:AREA1PADS]), - .ENABLE_INP_H(loop1_io[TOTAL_PADS - 1:AREA1PADS]), - .ENABLE_VDDA_H(porb_h), - .ENABLE_VSWITCH_H(vssio), - .ENABLE_VDDIO(vccd), - .INP_DIS(inp_dis[TOTAL_PADS - 1:AREA1PADS]), - .IB_MODE_SEL(ib_mode_sel[TOTAL_PADS - 1:AREA1PADS]), - .VTRIP_SEL(vtrip_sel[TOTAL_PADS - 1:AREA1PADS]), - .SLOW(slow_sel[TOTAL_PADS - 1:AREA1PADS]), - .HLD_OVR(holdover[TOTAL_PADS - 1:AREA1PADS]), - .ANALOG_EN(analog_en[TOTAL_PADS - 1:AREA1PADS]), - .ANALOG_SEL(analog_sel[TOTAL_PADS - 1:AREA1PADS]), - .ANALOG_POL(analog_pol[TOTAL_PADS - 1:AREA1PADS]), - .DM(dm[TOTAL_PADS*3 - 1:AREA1PADS*3]), - .PAD_A_NOESD_H({no_connect_2a, analog_noesd_io[TOTAL_PADS - 10:AREA1PADS - 7]}), - .PAD_A_ESD_0_H({no_connect_2b, analog_io[TOTAL_PADS - 10:AREA1PADS - 7]}), - .PAD_A_ESD_1_H(), - .IN(io_in[TOTAL_PADS - 1:AREA1PADS]), - .IN_H(io_in_3v3[TOTAL_PADS - 1:AREA1PADS]), - .TIE_HI_ESD(), - .TIE_LO_ESD(loop1_io[TOTAL_PADS - 1:AREA1PADS]) - ); - -endmodule -// `default_nettype wire
diff --git a/caravel/rtl/mprj_logic_high.v b/caravel/rtl/mprj_logic_high.v deleted file mode 100644 index 8801cc8..0000000 --- a/caravel/rtl/mprj_logic_high.v +++ /dev/null
@@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -module mprj_logic_high ( -`ifdef USE_POWER_PINS - inout vccd1, - inout vssd1, -`endif - output [461:0] HI -); -sky130_fd_sc_hd__conb_1 insts [461:0] ( -`ifdef USE_POWER_PINS - .VPWR(vccd1), - .VGND(vssd1), - .VPB(vccd1), - .VNB(vssd1), -`endif - .HI(HI), - .LO() - ); -endmodule
diff --git a/caravel/rtl/pads.v b/caravel/rtl/pads.v deleted file mode 100644 index f89ba90..0000000 --- a/caravel/rtl/pads.v +++ /dev/null
@@ -1,172 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -// `default_nettype none -`ifndef TOP_ROUTING - `define USER1_ABUTMENT_PINS \ - .AMUXBUS_A(analog_a),\ - .AMUXBUS_B(analog_b),\ - .VSSA(vssa1),\ - .VDDA(vdda1),\ - .VSWITCH(vddio),\ - .VDDIO_Q(vddio_q),\ - .VCCHIB(vccd),\ - .VDDIO(vddio),\ - .VCCD(vccd1),\ - .VSSIO(vssio),\ - .VSSD(vssd1),\ - .VSSIO_Q(vssio_q) - - `define USER2_ABUTMENT_PINS \ - .AMUXBUS_A(analog_a),\ - .AMUXBUS_B(analog_b),\ - .VSSA(vssa2),\ - .VDDA(vdda2),\ - .VSWITCH(vddio),\ - .VDDIO_Q(vddio_q),\ - .VCCHIB(vccd),\ - .VDDIO(vddio),\ - .VCCD(vccd2),\ - .VSSIO(vssio),\ - .VSSD(vssd2),\ - .VSSIO_Q(vssio_q) - - `define MGMT_ABUTMENT_PINS \ - .AMUXBUS_A(analog_a),\ - .AMUXBUS_B(analog_b),\ - .VSSA(vssa),\ - .VDDA(vdda),\ - .VSWITCH(vddio),\ - .VDDIO_Q(vddio_q),\ - .VCCHIB(vccd),\ - .VDDIO(vddio),\ - .VCCD(vccd),\ - .VSSIO(vssio),\ - .VSSD(vssd),\ - .VSSIO_Q(vssio_q) -`else - `define USER1_ABUTMENT_PINS - `define USER2_ABUTMENT_PINS - `define MGMT_ABUTMENT_PINS -`endif - -`define HVCLAMP_PINS(H,L) \ - .DRN_HVC(H), \ - .SRC_BDY_HVC(L) - -`define LVCLAMP_PINS(H1,L1,H2,L2,L3) \ - .BDY2_B2B(L3), \ - .DRN_LVC1(H1), \ - .DRN_LVC2(H2), \ - .SRC_BDY_LVC1(L1), \ - .SRC_BDY_LVC2(L2) - -`define INPUT_PAD(X,Y) \ - wire loop_``X; \ - sky130_ef_io__gpiov2_pad_wrapped X``_pad ( \ - `MGMT_ABUTMENT_PINS \ - `ifndef TOP_ROUTING \ - ,.PAD(X), \ - `endif \ - .OUT(vssd), \ - .OE_N(vccd), \ - .HLD_H_N(vddio), \ - .ENABLE_H(porb_h), \ - .ENABLE_INP_H(loop_``X), \ - .ENABLE_VDDA_H(porb_h), \ - .ENABLE_VSWITCH_H(vssa), \ - .ENABLE_VDDIO(vccd), \ - .INP_DIS(por), \ - .IB_MODE_SEL(vssd), \ - .VTRIP_SEL(vssd), \ - .SLOW(vssd), \ - .HLD_OVR(vssd), \ - .ANALOG_EN(vssd), \ - .ANALOG_SEL(vssd), \ - .ANALOG_POL(vssd), \ - .DM({vssd, vssd, vccd}), \ - .PAD_A_NOESD_H(), \ - .PAD_A_ESD_0_H(), \ - .PAD_A_ESD_1_H(), \ - .IN(Y), \ - .IN_H(), \ - .TIE_HI_ESD(), \ - .TIE_LO_ESD(loop_``X) ) - -`define OUTPUT_PAD(X,Y,INPUT_DIS,OUT_EN_N) \ - wire loop_``X; \ - sky130_ef_io__gpiov2_pad_wrapped X``_pad ( \ - `MGMT_ABUTMENT_PINS \ - `ifndef TOP_ROUTING \ - ,.PAD(X), \ - `endif \ - .OUT(Y), \ - .OE_N(OUT_EN_N), \ - .HLD_H_N(vddio), \ - .ENABLE_H(porb_h), \ - .ENABLE_INP_H(loop_``X), \ - .ENABLE_VDDA_H(porb_h), \ - .ENABLE_VSWITCH_H(vssa), \ - .ENABLE_VDDIO(vccd), \ - .INP_DIS(INPUT_DIS), \ - .IB_MODE_SEL(vssd), \ - .VTRIP_SEL(vssd), \ - .SLOW(vssd), \ - .HLD_OVR(vssd), \ - .ANALOG_EN(vssd), \ - .ANALOG_SEL(vssd), \ - .ANALOG_POL(vssd), \ - .DM({vccd, vccd, vssd}), \ - .PAD_A_NOESD_H(), \ - .PAD_A_ESD_0_H(), \ - .PAD_A_ESD_1_H(), \ - .IN(), \ - .IN_H(), \ - .TIE_HI_ESD(), \ - .TIE_LO_ESD(loop_``X)) - -`define INOUT_PAD(X,Y,Y_OUT,INPUT_DIS,OUT_EN_N,MODE) \ - wire loop_``X; \ - sky130_ef_io__gpiov2_pad_wrapped X``_pad ( \ - `MGMT_ABUTMENT_PINS \ - `ifndef TOP_ROUTING \ - ,.PAD(X), \ - `endif \ - .OUT(Y_OUT), \ - .OE_N(OUT_EN_N), \ - .HLD_H_N(vddio), \ - .ENABLE_H(porb_h), \ - .ENABLE_INP_H(loop_``X), \ - .ENABLE_VDDA_H(porb_h), \ - .ENABLE_VSWITCH_H(vssa), \ - .ENABLE_VDDIO(vccd), \ - .INP_DIS(INPUT_DIS), \ - .IB_MODE_SEL(vssd), \ - .VTRIP_SEL(vssd), \ - .SLOW(vssd), \ - .HLD_OVR(vssd), \ - .ANALOG_EN(vssd), \ - .ANALOG_SEL(vssd), \ - .ANALOG_POL(vssd), \ - .DM(MODE), \ - .PAD_A_NOESD_H(), \ - .PAD_A_ESD_0_H(), \ - .PAD_A_ESD_1_H(), \ - .IN(Y), \ - .IN_H(), \ - .TIE_HI_ESD(), \ - .TIE_LO_ESD(loop_``X) ) - -// `default_nettype wire
diff --git a/caravel/rtl/picorv32.v b/caravel/rtl/picorv32.v deleted file mode 100644 index 1316273..0000000 --- a/caravel/rtl/picorv32.v +++ /dev/null
@@ -1,3048 +0,0 @@ -`default_nettype none -/* - * SPDX-FileCopyrightText: 2015 Clifford Wolf - * PicoRV32 -- A Small RISC-V (RV32I) Processor Core - * - * Copyright (C) 2015 Clifford Wolf <clifford@clifford.at> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * SPDX-License-Identifier: ISC - */ - -/* verilator lint_off WIDTH */ -/* verilator lint_off PINMISSING */ -/* verilator lint_off CASEOVERLAP */ -/* verilator lint_off CASEINCOMPLETE */ - -`timescale 1 ns / 1 ps -// `define DEBUGNETS -// `define DEBUGREGS -// `define DEBUGASM -// `define DEBUG - -`ifdef DEBUG - `define debug(debug_command) debug_command -`else - `define debug(debug_command) -`endif - -`ifdef FORMAL - `define FORMAL_KEEP (* keep *) - `define assert(assert_expr) assert(assert_expr) -`else - `ifdef DEBUGNETS - `define FORMAL_KEEP (* keep *) - `else - `define FORMAL_KEEP - `endif - `define assert(assert_expr) empty_statement -`endif - -// uncomment this for register file in extra module -// `define PICORV32_REGS picorv32_regs - -// this macro can be used to check if the verilog files in your -// design are read in the correct order. -`define PICORV32_V - - -/*************************************************************** - * picorv32 - ***************************************************************/ - -module picorv32 #( - parameter [ 0:0] ENABLE_COUNTERS = 1, - parameter [ 0:0] ENABLE_COUNTERS64 = 1, - parameter [ 0:0] ENABLE_REGS_16_31 = 1, - parameter [ 0:0] ENABLE_REGS_DUALPORT = 1, - parameter [ 0:0] LATCHED_MEM_RDATA = 0, - parameter [ 0:0] TWO_STAGE_SHIFT = 1, - parameter [ 0:0] BARREL_SHIFTER = 0, - parameter [ 0:0] TWO_CYCLE_COMPARE = 0, - parameter [ 0:0] TWO_CYCLE_ALU = 0, - parameter [ 0:0] COMPRESSED_ISA = 0, - parameter [ 0:0] CATCH_MISALIGN = 1, - parameter [ 0:0] CATCH_ILLINSN = 1, - parameter [ 0:0] ENABLE_PCPI = 0, - parameter [ 0:0] ENABLE_MUL = 0, - parameter [ 0:0] ENABLE_FAST_MUL = 0, - parameter [ 0:0] ENABLE_DIV = 0, - parameter [ 0:0] ENABLE_IRQ = 0, - parameter [ 0:0] ENABLE_IRQ_QREGS = 1, - parameter [ 0:0] ENABLE_IRQ_TIMER = 1, - parameter [ 0:0] ENABLE_TRACE = 0, - parameter [ 0:0] REGS_INIT_ZERO = 0, - parameter [31:0] MASKED_IRQ = 32'h 0000_0000, - parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff, - parameter [31:0] PROGADDR_RESET = 32'h 0000_0000, - parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010, - parameter [31:0] STACKADDR = 32'h ffff_ffff -) ( - input clk, resetn, - output reg trap, - - output reg mem_valid, - output reg mem_instr, - input mem_ready, - - output reg [31:0] mem_addr, - output reg [31:0] mem_wdata, - output reg [ 3:0] mem_wstrb, - input [31:0] mem_rdata, - - // Look-Ahead Interface - output mem_la_read, - output mem_la_write, - output [31:0] mem_la_addr, - output reg [31:0] mem_la_wdata, - output reg [ 3:0] mem_la_wstrb, - - // Pico Co-Processor Interface (PCPI) - output reg pcpi_valid, - output reg [31:0] pcpi_insn, - output [31:0] pcpi_rs1, - output [31:0] pcpi_rs2, - input pcpi_wr, - input [31:0] pcpi_rd, - input pcpi_wait, - input pcpi_ready, - - // IRQ Interface - input [31:0] irq, - output reg [31:0] eoi, - -`ifdef RISCV_FORMAL - output reg rvfi_valid, - output reg [63:0] rvfi_order, - output reg [31:0] rvfi_insn, - output reg rvfi_trap, - output reg rvfi_halt, - output reg rvfi_intr, - output reg [ 1:0] rvfi_mode, - output reg [ 1:0] rvfi_ixl, - output reg [ 4:0] rvfi_rs1_addr, - output reg [ 4:0] rvfi_rs2_addr, - output reg [31:0] rvfi_rs1_rdata, - output reg [31:0] rvfi_rs2_rdata, - output reg [ 4:0] rvfi_rd_addr, - output reg [31:0] rvfi_rd_wdata, - output reg [31:0] rvfi_pc_rdata, - output reg [31:0] rvfi_pc_wdata, - output reg [31:0] rvfi_mem_addr, - output reg [ 3:0] rvfi_mem_rmask, - output reg [ 3:0] rvfi_mem_wmask, - output reg [31:0] rvfi_mem_rdata, - output reg [31:0] rvfi_mem_wdata, - - output reg [63:0] rvfi_csr_mcycle_rmask, - output reg [63:0] rvfi_csr_mcycle_wmask, - output reg [63:0] rvfi_csr_mcycle_rdata, - output reg [63:0] rvfi_csr_mcycle_wdata, - - output reg [63:0] rvfi_csr_minstret_rmask, - output reg [63:0] rvfi_csr_minstret_wmask, - output reg [63:0] rvfi_csr_minstret_rdata, - output reg [63:0] rvfi_csr_minstret_wdata, -`endif - - // Trace Interface - output reg trace_valid, - output reg [35:0] trace_data -); - localparam integer irq_timer = 0; - localparam integer irq_ebreak = 1; - localparam integer irq_buserror = 2; - - localparam integer irqregs_offset = ENABLE_REGS_16_31 ? 32 : 16; - localparam integer regfile_size = (ENABLE_REGS_16_31 ? 32 : 16) + 4*ENABLE_IRQ*ENABLE_IRQ_QREGS; - localparam integer regindex_bits = (ENABLE_REGS_16_31 ? 5 : 4) + ENABLE_IRQ*ENABLE_IRQ_QREGS; - - localparam WITH_PCPI = ENABLE_PCPI || ENABLE_MUL || ENABLE_FAST_MUL || ENABLE_DIV; - - localparam [35:0] TRACE_BRANCH = {4'b 0001, 32'b 0}; - localparam [35:0] TRACE_ADDR = {4'b 0010, 32'b 0}; - localparam [35:0] TRACE_IRQ = {4'b 1000, 32'b 0}; - - reg [63:0] count_cycle, count_instr; - reg [31:0] reg_pc, reg_next_pc, reg_op1, reg_op2, reg_out; - reg [4:0] reg_sh; - - reg [31:0] next_insn_opcode; - reg [31:0] dbg_insn_opcode; - reg [31:0] dbg_insn_addr; - - wire dbg_mem_valid = mem_valid; - wire dbg_mem_instr = mem_instr; - wire dbg_mem_ready = mem_ready; - wire [31:0] dbg_mem_addr = mem_addr; - wire [31:0] dbg_mem_wdata = mem_wdata; - wire [ 3:0] dbg_mem_wstrb = mem_wstrb; - wire [31:0] dbg_mem_rdata = mem_rdata; - - assign pcpi_rs1 = reg_op1; - assign pcpi_rs2 = reg_op2; - - wire [31:0] next_pc; - - reg irq_delay; - reg irq_active; - reg [31:0] irq_mask; - reg [31:0] irq_pending; - reg [31:0] timer; - -`ifndef PICORV32_REGS - reg [31:0] cpuregs [0:regfile_size-1]; - - integer i; - initial begin - if (REGS_INIT_ZERO) begin - for (i = 0; i < regfile_size; i = i+1) - cpuregs[i] = 0; - end - end -`endif - - task empty_statement; - // This task is used by the `assert directive in non-formal mode to - // avoid empty statement (which are unsupported by plain Verilog syntax). - begin end - endtask - -`ifdef DEBUGREGS - wire [31:0] dbg_reg_x0 = 0; - wire [31:0] dbg_reg_x1 = cpuregs[1]; - wire [31:0] dbg_reg_x2 = cpuregs[2]; - wire [31:0] dbg_reg_x3 = cpuregs[3]; - wire [31:0] dbg_reg_x4 = cpuregs[4]; - wire [31:0] dbg_reg_x5 = cpuregs[5]; - wire [31:0] dbg_reg_x6 = cpuregs[6]; - wire [31:0] dbg_reg_x7 = cpuregs[7]; - wire [31:0] dbg_reg_x8 = cpuregs[8]; - wire [31:0] dbg_reg_x9 = cpuregs[9]; - wire [31:0] dbg_reg_x10 = cpuregs[10]; - wire [31:0] dbg_reg_x11 = cpuregs[11]; - wire [31:0] dbg_reg_x12 = cpuregs[12]; - wire [31:0] dbg_reg_x13 = cpuregs[13]; - wire [31:0] dbg_reg_x14 = cpuregs[14]; - wire [31:0] dbg_reg_x15 = cpuregs[15]; - wire [31:0] dbg_reg_x16 = cpuregs[16]; - wire [31:0] dbg_reg_x17 = cpuregs[17]; - wire [31:0] dbg_reg_x18 = cpuregs[18]; - wire [31:0] dbg_reg_x19 = cpuregs[19]; - wire [31:0] dbg_reg_x20 = cpuregs[20]; - wire [31:0] dbg_reg_x21 = cpuregs[21]; - wire [31:0] dbg_reg_x22 = cpuregs[22]; - wire [31:0] dbg_reg_x23 = cpuregs[23]; - wire [31:0] dbg_reg_x24 = cpuregs[24]; - wire [31:0] dbg_reg_x25 = cpuregs[25]; - wire [31:0] dbg_reg_x26 = cpuregs[26]; - wire [31:0] dbg_reg_x27 = cpuregs[27]; - wire [31:0] dbg_reg_x28 = cpuregs[28]; - wire [31:0] dbg_reg_x29 = cpuregs[29]; - wire [31:0] dbg_reg_x30 = cpuregs[30]; - wire [31:0] dbg_reg_x31 = cpuregs[31]; -`endif - - // Internal PCPI Cores - - wire pcpi_mul_wr; - wire [31:0] pcpi_mul_rd; - wire pcpi_mul_wait; - wire pcpi_mul_ready; - - wire pcpi_div_wr; - wire [31:0] pcpi_div_rd; - wire pcpi_div_wait; - wire pcpi_div_ready; - - reg pcpi_int_wr; - reg [31:0] pcpi_int_rd; - reg pcpi_int_wait; - reg pcpi_int_ready; - - generate if (ENABLE_FAST_MUL) begin - picorv32_pcpi_fast_mul pcpi_mul ( - .clk (clk ), - .resetn (resetn ), - .pcpi_valid(pcpi_valid ), - .pcpi_insn (pcpi_insn ), - .pcpi_rs1 (pcpi_rs1 ), - .pcpi_rs2 (pcpi_rs2 ), - .pcpi_wr (pcpi_mul_wr ), - .pcpi_rd (pcpi_mul_rd ), - .pcpi_wait (pcpi_mul_wait ), - .pcpi_ready(pcpi_mul_ready ) - ); - end else if (ENABLE_MUL) begin - picorv32_pcpi_mul pcpi_mul ( - .clk (clk ), - .resetn (resetn ), - .pcpi_valid(pcpi_valid ), - .pcpi_insn (pcpi_insn ), - .pcpi_rs1 (pcpi_rs1 ), - .pcpi_rs2 (pcpi_rs2 ), - .pcpi_wr (pcpi_mul_wr ), - .pcpi_rd (pcpi_mul_rd ), - .pcpi_wait (pcpi_mul_wait ), - .pcpi_ready(pcpi_mul_ready ) - ); - end else begin - assign pcpi_mul_wr = 0; - assign pcpi_mul_rd = 32'bx; - assign pcpi_mul_wait = 0; - assign pcpi_mul_ready = 0; - end endgenerate - - generate if (ENABLE_DIV) begin - picorv32_pcpi_div pcpi_div ( - .clk (clk ), - .resetn (resetn ), - .pcpi_valid(pcpi_valid ), - .pcpi_insn (pcpi_insn ), - .pcpi_rs1 (pcpi_rs1 ), - .pcpi_rs2 (pcpi_rs2 ), - .pcpi_wr (pcpi_div_wr ), - .pcpi_rd (pcpi_div_rd ), - .pcpi_wait (pcpi_div_wait ), - .pcpi_ready(pcpi_div_ready ) - ); - end else begin - assign pcpi_div_wr = 0; - assign pcpi_div_rd = 32'bx; - assign pcpi_div_wait = 0; - assign pcpi_div_ready = 0; - end endgenerate - - always @* begin - pcpi_int_wr = 0; - pcpi_int_rd = 32'bx; - pcpi_int_wait = |{ENABLE_PCPI && pcpi_wait, (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_wait, ENABLE_DIV && pcpi_div_wait}; - pcpi_int_ready = |{ENABLE_PCPI && pcpi_ready, (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_ready, ENABLE_DIV && pcpi_div_ready}; - - (* parallel_case *) - case (1'b1) - ENABLE_PCPI && pcpi_ready: begin - pcpi_int_wr = ENABLE_PCPI ? pcpi_wr : 0; - pcpi_int_rd = ENABLE_PCPI ? pcpi_rd : 0; - end - (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_ready: begin - pcpi_int_wr = pcpi_mul_wr; - pcpi_int_rd = pcpi_mul_rd; - end - ENABLE_DIV && pcpi_div_ready: begin - pcpi_int_wr = pcpi_div_wr; - pcpi_int_rd = pcpi_div_rd; - end - endcase - end - - - // Memory Interface - - reg [1:0] mem_state; - reg [1:0] mem_wordsize; - reg [31:0] mem_rdata_word; - reg [31:0] mem_rdata_q; - reg mem_do_prefetch; - reg mem_do_rinst; - reg mem_do_rdata; - reg mem_do_wdata; - - wire mem_xfer; - reg mem_la_secondword, mem_la_firstword_reg, last_mem_valid; - wire mem_la_firstword = COMPRESSED_ISA && (mem_do_prefetch || mem_do_rinst) && next_pc[1] && !mem_la_secondword; - wire mem_la_firstword_xfer = COMPRESSED_ISA && mem_xfer && (!last_mem_valid ? mem_la_firstword : mem_la_firstword_reg); - - reg prefetched_high_word; - reg clear_prefetched_high_word; - reg [15:0] mem_16bit_buffer; - - wire [31:0] mem_rdata_latched_noshuffle; - wire [31:0] mem_rdata_latched; - - wire mem_la_use_prefetched_high_word = COMPRESSED_ISA && mem_la_firstword && prefetched_high_word && !clear_prefetched_high_word; - assign mem_xfer = (mem_valid && mem_ready) || (mem_la_use_prefetched_high_word && mem_do_rinst); - - wire mem_busy = |{mem_do_prefetch, mem_do_rinst, mem_do_rdata, mem_do_wdata}; - wire mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst)) && - (!mem_la_firstword || (~&mem_rdata_latched[1:0] && mem_xfer)); - - assign mem_la_write = resetn && !mem_state && mem_do_wdata; - assign mem_la_read = resetn && ((!mem_la_use_prefetched_high_word && !mem_state && (mem_do_rinst || mem_do_prefetch || mem_do_rdata)) || - (COMPRESSED_ISA && mem_xfer && (!last_mem_valid ? mem_la_firstword : mem_la_firstword_reg) && !mem_la_secondword && &mem_rdata_latched[1:0])); - assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2] + mem_la_firstword_xfer, 2'b00} : {reg_op1[31:2], 2'b00}; - - assign mem_rdata_latched_noshuffle = (mem_xfer || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q; - - assign mem_rdata_latched = COMPRESSED_ISA && mem_la_use_prefetched_high_word ? {16'bx, mem_16bit_buffer} : - COMPRESSED_ISA && mem_la_secondword ? {mem_rdata_latched_noshuffle[15:0], mem_16bit_buffer} : - COMPRESSED_ISA && mem_la_firstword ? {16'bx, mem_rdata_latched_noshuffle[31:16]} : mem_rdata_latched_noshuffle; - - always @(posedge clk) begin - if (!resetn) begin - mem_la_firstword_reg <= 0; - last_mem_valid <= 0; - end else begin - if (!last_mem_valid) - mem_la_firstword_reg <= mem_la_firstword; - last_mem_valid <= mem_valid && !mem_ready; - end - end - - always @* begin - (* full_case *) - case (mem_wordsize) - 0: begin - mem_la_wdata = reg_op2; - mem_la_wstrb = 4'b1111; - mem_rdata_word = mem_rdata; - end - 1: begin - mem_la_wdata = {2{reg_op2[15:0]}}; - mem_la_wstrb = reg_op1[1] ? 4'b1100 : 4'b0011; - case (reg_op1[1]) - 1'b0: mem_rdata_word = {16'b0, mem_rdata[15: 0]}; - 1'b1: mem_rdata_word = {16'b0, mem_rdata[31:16]}; - endcase - end - 2: begin - mem_la_wdata = {4{reg_op2[7:0]}}; - mem_la_wstrb = 4'b0001 << reg_op1[1:0]; - case (reg_op1[1:0]) - 2'b00: mem_rdata_word = {24'b0, mem_rdata[ 7: 0]}; - 2'b01: mem_rdata_word = {24'b0, mem_rdata[15: 8]}; - 2'b10: mem_rdata_word = {24'b0, mem_rdata[23:16]}; - 2'b11: mem_rdata_word = {24'b0, mem_rdata[31:24]}; - endcase - end - endcase - end - - always @(posedge clk) begin - if (mem_xfer) begin - mem_rdata_q <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata; - next_insn_opcode <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata; - end - - if (COMPRESSED_ISA && mem_done && (mem_do_prefetch || mem_do_rinst)) begin - case (mem_rdata_latched[1:0]) - 2'b00: begin // Quadrant 0 - case (mem_rdata_latched[15:13]) - 3'b000: begin // C.ADDI4SPN - mem_rdata_q[14:12] <= 3'b000; - mem_rdata_q[31:20] <= {2'b0, mem_rdata_latched[10:7], mem_rdata_latched[12:11], mem_rdata_latched[5], mem_rdata_latched[6], 2'b00}; - end - 3'b010: begin // C.LW - mem_rdata_q[31:20] <= {5'b0, mem_rdata_latched[5], mem_rdata_latched[12:10], mem_rdata_latched[6], 2'b00}; - mem_rdata_q[14:12] <= 3'b 010; - end - 3'b 110: begin // C.SW - {mem_rdata_q[31:25], mem_rdata_q[11:7]} <= {5'b0, mem_rdata_latched[5], mem_rdata_latched[12:10], mem_rdata_latched[6], 2'b00}; - mem_rdata_q[14:12] <= 3'b 010; - end - endcase - end - 2'b01: begin // Quadrant 1 - case (mem_rdata_latched[15:13]) - 3'b 000: begin // C.ADDI - mem_rdata_q[14:12] <= 3'b000; - mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]}); - end - 3'b 010: begin // C.LI - mem_rdata_q[14:12] <= 3'b000; - mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]}); - end - 3'b 011: begin - if (mem_rdata_latched[11:7] == 2) begin // C.ADDI16SP - mem_rdata_q[14:12] <= 3'b000; - mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[4:3], - mem_rdata_latched[5], mem_rdata_latched[2], mem_rdata_latched[6], 4'b 0000}); - end else begin // C.LUI - mem_rdata_q[31:12] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]}); - end - end - 3'b100: begin - if (mem_rdata_latched[11:10] == 2'b00) begin // C.SRLI - mem_rdata_q[31:25] <= 7'b0000000; - mem_rdata_q[14:12] <= 3'b 101; - end - if (mem_rdata_latched[11:10] == 2'b01) begin // C.SRAI - mem_rdata_q[31:25] <= 7'b0100000; - mem_rdata_q[14:12] <= 3'b 101; - end - if (mem_rdata_latched[11:10] == 2'b10) begin // C.ANDI - mem_rdata_q[14:12] <= 3'b111; - mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]}); - end - if (mem_rdata_latched[12:10] == 3'b011) begin // C.SUB, C.XOR, C.OR, C.AND - if (mem_rdata_latched[6:5] == 2'b00) mem_rdata_q[14:12] <= 3'b000; - if (mem_rdata_latched[6:5] == 2'b01) mem_rdata_q[14:12] <= 3'b100; - if (mem_rdata_latched[6:5] == 2'b10) mem_rdata_q[14:12] <= 3'b110; - if (mem_rdata_latched[6:5] == 2'b11) mem_rdata_q[14:12] <= 3'b111; - mem_rdata_q[31:25] <= mem_rdata_latched[6:5] == 2'b00 ? 7'b0100000 : 7'b0000000; - end - end - 3'b 110: begin // C.BEQZ - mem_rdata_q[14:12] <= 3'b000; - { mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8] } <= - $signed({mem_rdata_latched[12], mem_rdata_latched[6:5], mem_rdata_latched[2], - mem_rdata_latched[11:10], mem_rdata_latched[4:3]}); - end - 3'b 111: begin // C.BNEZ - mem_rdata_q[14:12] <= 3'b001; - { mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8] } <= - $signed({mem_rdata_latched[12], mem_rdata_latched[6:5], mem_rdata_latched[2], - mem_rdata_latched[11:10], mem_rdata_latched[4:3]}); - end - endcase - end - 2'b10: begin // Quadrant 2 - case (mem_rdata_latched[15:13]) - 3'b000: begin // C.SLLI - mem_rdata_q[31:25] <= 7'b0000000; - mem_rdata_q[14:12] <= 3'b 001; - end - 3'b010: begin // C.LWSP - mem_rdata_q[31:20] <= {4'b0, mem_rdata_latched[3:2], mem_rdata_latched[12], mem_rdata_latched[6:4], 2'b00}; - mem_rdata_q[14:12] <= 3'b 010; - end - 3'b100: begin - if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] == 0) begin // C.JR - mem_rdata_q[14:12] <= 3'b000; - mem_rdata_q[31:20] <= 12'b0; - end - if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] != 0) begin // C.MV - mem_rdata_q[14:12] <= 3'b000; - mem_rdata_q[31:25] <= 7'b0000000; - end - if (mem_rdata_latched[12] != 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JALR - mem_rdata_q[14:12] <= 3'b000; - mem_rdata_q[31:20] <= 12'b0; - end - if (mem_rdata_latched[12] != 0 && mem_rdata_latched[6:2] != 0) begin // C.ADD - mem_rdata_q[14:12] <= 3'b000; - mem_rdata_q[31:25] <= 7'b0000000; - end - end - 3'b110: begin // C.SWSP - {mem_rdata_q[31:25], mem_rdata_q[11:7]} <= {4'b0, mem_rdata_latched[8:7], mem_rdata_latched[12:9], 2'b00}; - mem_rdata_q[14:12] <= 3'b 010; - end - endcase - end - endcase - end - end - - always @(posedge clk) begin - if (resetn && !trap) begin - if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) - `assert(!mem_do_wdata); - - if (mem_do_prefetch || mem_do_rinst) - `assert(!mem_do_rdata); - - if (mem_do_rdata) - `assert(!mem_do_prefetch && !mem_do_rinst); - - if (mem_do_wdata) - `assert(!(mem_do_prefetch || mem_do_rinst || mem_do_rdata)); - - if (mem_state == 2 || mem_state == 3) - `assert(mem_valid || mem_do_prefetch); - end - end - - always @(posedge clk) begin - if (!resetn || trap) begin - if (!resetn) - mem_state <= 0; - if (!resetn || mem_ready) - mem_valid <= 0; - mem_la_secondword <= 0; - prefetched_high_word <= 0; - end else begin - if (mem_la_read || mem_la_write) begin - mem_addr <= mem_la_addr; - mem_wstrb <= mem_la_wstrb & {4{mem_la_write}}; - end - if (mem_la_write) begin - mem_wdata <= mem_la_wdata; - end - case (mem_state) - 0: begin - if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) begin - mem_valid <= !mem_la_use_prefetched_high_word; - mem_instr <= mem_do_prefetch || mem_do_rinst; - mem_wstrb <= 0; - mem_state <= 1; - end - if (mem_do_wdata) begin - mem_valid <= 1; - mem_instr <= 0; - mem_state <= 2; - end - end - 1: begin - `assert(mem_wstrb == 0); - `assert(mem_do_prefetch || mem_do_rinst || mem_do_rdata); - `assert(mem_valid == !mem_la_use_prefetched_high_word); - `assert(mem_instr == (mem_do_prefetch || mem_do_rinst)); - if (mem_xfer) begin - if (COMPRESSED_ISA && mem_la_read) begin - mem_valid <= 1; - mem_la_secondword <= 1; - if (!mem_la_use_prefetched_high_word) - mem_16bit_buffer <= mem_rdata[31:16]; - end else begin - mem_valid <= 0; - mem_la_secondword <= 0; - if (COMPRESSED_ISA && !mem_do_rdata) begin - if (~&mem_rdata[1:0] || mem_la_secondword) begin - mem_16bit_buffer <= mem_rdata[31:16]; - prefetched_high_word <= 1; - end else begin - prefetched_high_word <= 0; - end - end - mem_state <= mem_do_rinst || mem_do_rdata ? 0 : 3; - end - end - end - 2: begin - `assert(mem_wstrb != 0); - `assert(mem_do_wdata); - if (mem_xfer) begin - mem_valid <= 0; - mem_state <= 0; - end - end - 3: begin - `assert(mem_wstrb == 0); - `assert(mem_do_prefetch); - if (mem_do_rinst) begin - mem_state <= 0; - end - end - endcase - end - - if (clear_prefetched_high_word) - prefetched_high_word <= 0; - end - - - // Instruction Decoder - - reg instr_lui, instr_auipc, instr_jal, instr_jalr; - reg instr_beq, instr_bne, instr_blt, instr_bge, instr_bltu, instr_bgeu; - reg instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw; - reg instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai; - reg instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and; - reg instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh, instr_ecall_ebreak; - reg instr_getq, instr_setq, instr_retirq, instr_maskirq, instr_waitirq, instr_timer; - wire instr_trap; - - reg [regindex_bits-1:0] decoded_rd, decoded_rs1, decoded_rs2; - reg [31:0] decoded_imm, decoded_imm_j; - reg decoder_trigger; - reg decoder_trigger_q; - reg decoder_pseudo_trigger; - reg decoder_pseudo_trigger_q; - reg compressed_instr; - - reg is_lui_auipc_jal; - reg is_lb_lh_lw_lbu_lhu; - reg is_slli_srli_srai; - reg is_jalr_addi_slti_sltiu_xori_ori_andi; - reg is_sb_sh_sw; - reg is_sll_srl_sra; - reg is_lui_auipc_jal_jalr_addi_add_sub; - reg is_slti_blt_slt; - reg is_sltiu_bltu_sltu; - reg is_beq_bne_blt_bge_bltu_bgeu; - reg is_lbu_lhu_lw; - reg is_alu_reg_imm; - reg is_alu_reg_reg; - reg is_compare; - - assign instr_trap = (CATCH_ILLINSN || WITH_PCPI) && !{instr_lui, instr_auipc, instr_jal, instr_jalr, - instr_beq, instr_bne, instr_blt, instr_bge, instr_bltu, instr_bgeu, - instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw, - instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai, - instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and, - instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh, - instr_getq, instr_setq, instr_retirq, instr_maskirq, instr_waitirq, instr_timer}; - - wire is_rdcycle_rdcycleh_rdinstr_rdinstrh; - assign is_rdcycle_rdcycleh_rdinstr_rdinstrh = |{instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh}; - - reg [63:0] new_ascii_instr; - `FORMAL_KEEP reg [63:0] dbg_ascii_instr; - `FORMAL_KEEP reg [31:0] dbg_insn_imm; - `FORMAL_KEEP reg [4:0] dbg_insn_rs1; - `FORMAL_KEEP reg [4:0] dbg_insn_rs2; - `FORMAL_KEEP reg [4:0] dbg_insn_rd; - `FORMAL_KEEP reg [31:0] dbg_rs1val; - `FORMAL_KEEP reg [31:0] dbg_rs2val; - `FORMAL_KEEP reg dbg_rs1val_valid; - `FORMAL_KEEP reg dbg_rs2val_valid; - - always @* begin - new_ascii_instr = ""; - - if (instr_lui) new_ascii_instr = "lui"; - if (instr_auipc) new_ascii_instr = "auipc"; - if (instr_jal) new_ascii_instr = "jal"; - if (instr_jalr) new_ascii_instr = "jalr"; - - if (instr_beq) new_ascii_instr = "beq"; - if (instr_bne) new_ascii_instr = "bne"; - if (instr_blt) new_ascii_instr = "blt"; - if (instr_bge) new_ascii_instr = "bge"; - if (instr_bltu) new_ascii_instr = "bltu"; - if (instr_bgeu) new_ascii_instr = "bgeu"; - - if (instr_lb) new_ascii_instr = "lb"; - if (instr_lh) new_ascii_instr = "lh"; - if (instr_lw) new_ascii_instr = "lw"; - if (instr_lbu) new_ascii_instr = "lbu"; - if (instr_lhu) new_ascii_instr = "lhu"; - if (instr_sb) new_ascii_instr = "sb"; - if (instr_sh) new_ascii_instr = "sh"; - if (instr_sw) new_ascii_instr = "sw"; - - if (instr_addi) new_ascii_instr = "addi"; - if (instr_slti) new_ascii_instr = "slti"; - if (instr_sltiu) new_ascii_instr = "sltiu"; - if (instr_xori) new_ascii_instr = "xori"; - if (instr_ori) new_ascii_instr = "ori"; - if (instr_andi) new_ascii_instr = "andi"; - if (instr_slli) new_ascii_instr = "slli"; - if (instr_srli) new_ascii_instr = "srli"; - if (instr_srai) new_ascii_instr = "srai"; - - if (instr_add) new_ascii_instr = "add"; - if (instr_sub) new_ascii_instr = "sub"; - if (instr_sll) new_ascii_instr = "sll"; - if (instr_slt) new_ascii_instr = "slt"; - if (instr_sltu) new_ascii_instr = "sltu"; - if (instr_xor) new_ascii_instr = "xor"; - if (instr_srl) new_ascii_instr = "srl"; - if (instr_sra) new_ascii_instr = "sra"; - if (instr_or) new_ascii_instr = "or"; - if (instr_and) new_ascii_instr = "and"; - - if (instr_rdcycle) new_ascii_instr = "rdcycle"; - if (instr_rdcycleh) new_ascii_instr = "rdcycleh"; - if (instr_rdinstr) new_ascii_instr = "rdinstr"; - if (instr_rdinstrh) new_ascii_instr = "rdinstrh"; - - if (instr_getq) new_ascii_instr = "getq"; - if (instr_setq) new_ascii_instr = "setq"; - if (instr_retirq) new_ascii_instr = "retirq"; - if (instr_maskirq) new_ascii_instr = "maskirq"; - if (instr_waitirq) new_ascii_instr = "waitirq"; - if (instr_timer) new_ascii_instr = "timer"; - end - - reg [63:0] q_ascii_instr; - reg [31:0] q_insn_imm; - reg [31:0] q_insn_opcode; - reg [4:0] q_insn_rs1; - reg [4:0] q_insn_rs2; - reg [4:0] q_insn_rd; - reg dbg_next; - - wire launch_next_insn; - reg dbg_valid_insn; - - reg [63:0] cached_ascii_instr; - reg [31:0] cached_insn_imm; - reg [31:0] cached_insn_opcode; - reg [4:0] cached_insn_rs1; - reg [4:0] cached_insn_rs2; - reg [4:0] cached_insn_rd; - - always @(posedge clk) begin - q_ascii_instr <= dbg_ascii_instr; - q_insn_imm <= dbg_insn_imm; - q_insn_opcode <= dbg_insn_opcode; - q_insn_rs1 <= dbg_insn_rs1; - q_insn_rs2 <= dbg_insn_rs2; - q_insn_rd <= dbg_insn_rd; - dbg_next <= launch_next_insn; - - if (!resetn || trap) - dbg_valid_insn <= 0; - else if (launch_next_insn) - dbg_valid_insn <= 1; - - if (decoder_trigger_q) begin - cached_ascii_instr <= new_ascii_instr; - cached_insn_imm <= decoded_imm; - if (&next_insn_opcode[1:0]) - cached_insn_opcode <= next_insn_opcode; - else - cached_insn_opcode <= {16'b0, next_insn_opcode[15:0]}; - cached_insn_rs1 <= decoded_rs1; - cached_insn_rs2 <= decoded_rs2; - cached_insn_rd <= decoded_rd; - end - - if (launch_next_insn) begin - dbg_insn_addr <= next_pc; - end - end - - always @* begin - dbg_ascii_instr = q_ascii_instr; - dbg_insn_imm = q_insn_imm; - dbg_insn_opcode = q_insn_opcode; - dbg_insn_rs1 = q_insn_rs1; - dbg_insn_rs2 = q_insn_rs2; - dbg_insn_rd = q_insn_rd; - - if (dbg_next) begin - if (decoder_pseudo_trigger_q) begin - dbg_ascii_instr = cached_ascii_instr; - dbg_insn_imm = cached_insn_imm; - dbg_insn_opcode = cached_insn_opcode; - dbg_insn_rs1 = cached_insn_rs1; - dbg_insn_rs2 = cached_insn_rs2; - dbg_insn_rd = cached_insn_rd; - end else begin - dbg_ascii_instr = new_ascii_instr; - if (&next_insn_opcode[1:0]) - dbg_insn_opcode = next_insn_opcode; - else - dbg_insn_opcode = {16'b0, next_insn_opcode[15:0]}; - dbg_insn_imm = decoded_imm; - dbg_insn_rs1 = decoded_rs1; - dbg_insn_rs2 = decoded_rs2; - dbg_insn_rd = decoded_rd; - end - end - end - -`ifdef DEBUGASM - always @(posedge clk) begin - if (dbg_next) begin - $display("debugasm %x %x %s", dbg_insn_addr, dbg_insn_opcode, dbg_ascii_instr ? dbg_ascii_instr : "*"); - end - end -`endif - -`ifdef DEBUG - always @(posedge clk) begin - if (dbg_next) begin - if (&dbg_insn_opcode[1:0]) - $display("DECODE: 0x%08x 0x%08x %-0s", dbg_insn_addr, dbg_insn_opcode, dbg_ascii_instr ? dbg_ascii_instr : "UNKNOWN"); - else - $display("DECODE: 0x%08x 0x%04x %-0s", dbg_insn_addr, dbg_insn_opcode[15:0], dbg_ascii_instr ? dbg_ascii_instr : "UNKNOWN"); - end - end -`endif - - always @(posedge clk) begin - is_lui_auipc_jal <= |{instr_lui, instr_auipc, instr_jal}; - is_lui_auipc_jal_jalr_addi_add_sub <= |{instr_lui, instr_auipc, instr_jal, instr_jalr, instr_addi, instr_add, instr_sub}; - is_slti_blt_slt <= |{instr_slti, instr_blt, instr_slt}; - is_sltiu_bltu_sltu <= |{instr_sltiu, instr_bltu, instr_sltu}; - is_lbu_lhu_lw <= |{instr_lbu, instr_lhu, instr_lw}; - is_compare <= |{is_beq_bne_blt_bge_bltu_bgeu, instr_slti, instr_slt, instr_sltiu, instr_sltu}; - - if (mem_do_rinst && mem_done) begin - instr_lui <= mem_rdata_latched[6:0] == 7'b0110111; - instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111; - instr_jal <= mem_rdata_latched[6:0] == 7'b1101111; - instr_jalr <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000; - instr_retirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ; - instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100 && ENABLE_IRQ; - - is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011; - is_lb_lh_lw_lbu_lhu <= mem_rdata_latched[6:0] == 7'b0000011; - is_sb_sh_sw <= mem_rdata_latched[6:0] == 7'b0100011; - is_alu_reg_imm <= mem_rdata_latched[6:0] == 7'b0010011; - is_alu_reg_reg <= mem_rdata_latched[6:0] == 7'b0110011; - - { decoded_imm_j[31:20], decoded_imm_j[10:1], decoded_imm_j[11], decoded_imm_j[19:12], decoded_imm_j[0] } <= $signed({mem_rdata_latched[31:12], 1'b0}); - - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= mem_rdata_latched[19:15]; - decoded_rs2 <= mem_rdata_latched[24:20]; - - if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS) - decoded_rs1[regindex_bits-1] <= 1; // instr_getq - - if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ) - decoded_rs1 <= ENABLE_IRQ_QREGS ? irqregs_offset : 3; // instr_retirq - - compressed_instr <= 0; - if (COMPRESSED_ISA && mem_rdata_latched[1:0] != 2'b11) begin - compressed_instr <= 1; - decoded_rd <= 0; - decoded_rs1 <= 0; - decoded_rs2 <= 0; - - { decoded_imm_j[31:11], decoded_imm_j[4], decoded_imm_j[9:8], decoded_imm_j[10], decoded_imm_j[6], - decoded_imm_j[7], decoded_imm_j[3:1], decoded_imm_j[5], decoded_imm_j[0] } <= $signed({mem_rdata_latched[12:2], 1'b0}); - - case (mem_rdata_latched[1:0]) - 2'b00: begin // Quadrant 0 - case (mem_rdata_latched[15:13]) - 3'b000: begin // C.ADDI4SPN - is_alu_reg_imm <= |mem_rdata_latched[12:5]; - decoded_rs1 <= 2; - decoded_rd <= 8 + mem_rdata_latched[4:2]; - end - 3'b010: begin // C.LW - is_lb_lh_lw_lbu_lhu <= 1; - decoded_rs1 <= 8 + mem_rdata_latched[9:7]; - decoded_rd <= 8 + mem_rdata_latched[4:2]; - end - 3'b110: begin // C.SW - is_sb_sh_sw <= 1; - decoded_rs1 <= 8 + mem_rdata_latched[9:7]; - decoded_rs2 <= 8 + mem_rdata_latched[4:2]; - end - endcase - end - 2'b01: begin // Quadrant 1 - case (mem_rdata_latched[15:13]) - 3'b000: begin // C.NOP / C.ADDI - is_alu_reg_imm <= 1; - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= mem_rdata_latched[11:7]; - end - 3'b001: begin // C.JAL - instr_jal <= 1; - decoded_rd <= 1; - end - 3'b 010: begin // C.LI - is_alu_reg_imm <= 1; - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= 0; - end - 3'b 011: begin - if (mem_rdata_latched[12] || mem_rdata_latched[6:2]) begin - if (mem_rdata_latched[11:7] == 2) begin // C.ADDI16SP - is_alu_reg_imm <= 1; - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= mem_rdata_latched[11:7]; - end else begin // C.LUI - instr_lui <= 1; - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= 0; - end - end - end - 3'b100: begin - if (!mem_rdata_latched[11] && !mem_rdata_latched[12]) begin // C.SRLI, C.SRAI - is_alu_reg_imm <= 1; - decoded_rd <= 8 + mem_rdata_latched[9:7]; - decoded_rs1 <= 8 + mem_rdata_latched[9:7]; - decoded_rs2 <= {mem_rdata_latched[12], mem_rdata_latched[6:2]}; - end - if (mem_rdata_latched[11:10] == 2'b10) begin // C.ANDI - is_alu_reg_imm <= 1; - decoded_rd <= 8 + mem_rdata_latched[9:7]; - decoded_rs1 <= 8 + mem_rdata_latched[9:7]; - end - if (mem_rdata_latched[12:10] == 3'b011) begin // C.SUB, C.XOR, C.OR, C.AND - is_alu_reg_reg <= 1; - decoded_rd <= 8 + mem_rdata_latched[9:7]; - decoded_rs1 <= 8 + mem_rdata_latched[9:7]; - decoded_rs2 <= 8 + mem_rdata_latched[4:2]; - end - end - 3'b101: begin // C.J - instr_jal <= 1; - end - 3'b110: begin // C.BEQZ - is_beq_bne_blt_bge_bltu_bgeu <= 1; - decoded_rs1 <= 8 + mem_rdata_latched[9:7]; - decoded_rs2 <= 0; - end - 3'b111: begin // C.BNEZ - is_beq_bne_blt_bge_bltu_bgeu <= 1; - decoded_rs1 <= 8 + mem_rdata_latched[9:7]; - decoded_rs2 <= 0; - end - endcase - end - 2'b10: begin // Quadrant 2 - case (mem_rdata_latched[15:13]) - 3'b000: begin // C.SLLI - if (!mem_rdata_latched[12]) begin - is_alu_reg_imm <= 1; - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= mem_rdata_latched[11:7]; - decoded_rs2 <= {mem_rdata_latched[12], mem_rdata_latched[6:2]}; - end - end - 3'b010: begin // C.LWSP - if (mem_rdata_latched[11:7]) begin - is_lb_lh_lw_lbu_lhu <= 1; - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= 2; - end - end - 3'b100: begin - if (mem_rdata_latched[12] == 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JR - instr_jalr <= 1; - decoded_rd <= 0; - decoded_rs1 <= mem_rdata_latched[11:7]; - end - if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] != 0) begin // C.MV - is_alu_reg_reg <= 1; - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= 0; - decoded_rs2 <= mem_rdata_latched[6:2]; - end - if (mem_rdata_latched[12] != 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JALR - instr_jalr <= 1; - decoded_rd <= 1; - decoded_rs1 <= mem_rdata_latched[11:7]; - end - if (mem_rdata_latched[12] != 0 && mem_rdata_latched[6:2] != 0) begin // C.ADD - is_alu_reg_reg <= 1; - decoded_rd <= mem_rdata_latched[11:7]; - decoded_rs1 <= mem_rdata_latched[11:7]; - decoded_rs2 <= mem_rdata_latched[6:2]; - end - end - 3'b110: begin // C.SWSP - is_sb_sh_sw <= 1; - decoded_rs1 <= 2; - decoded_rs2 <= mem_rdata_latched[6:2]; - end - endcase - end - endcase - end - end - - if (decoder_trigger && !decoder_pseudo_trigger) begin - pcpi_insn <= WITH_PCPI ? mem_rdata_q : 'bx; - - instr_beq <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b000; - instr_bne <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b001; - instr_blt <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b100; - instr_bge <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b101; - instr_bltu <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b110; - instr_bgeu <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b111; - - instr_lb <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b000; - instr_lh <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b001; - instr_lw <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b010; - instr_lbu <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b100; - instr_lhu <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b101; - - instr_sb <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b000; - instr_sh <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b001; - instr_sw <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b010; - - instr_addi <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b000; - instr_slti <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b010; - instr_sltiu <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b011; - instr_xori <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b100; - instr_ori <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b110; - instr_andi <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b111; - - instr_slli <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000; - instr_srli <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000; - instr_srai <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000; - - instr_add <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0000000; - instr_sub <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0100000; - instr_sll <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000; - instr_slt <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b010 && mem_rdata_q[31:25] == 7'b0000000; - instr_sltu <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b011 && mem_rdata_q[31:25] == 7'b0000000; - instr_xor <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b100 && mem_rdata_q[31:25] == 7'b0000000; - instr_srl <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000; - instr_sra <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000; - instr_or <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b110 && mem_rdata_q[31:25] == 7'b0000000; - instr_and <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b111 && mem_rdata_q[31:25] == 7'b0000000; - - instr_rdcycle <= ((mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000000000000010) || - (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000000100000010)) && ENABLE_COUNTERS; - instr_rdcycleh <= ((mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000000000000010) || - (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000000100000010)) && ENABLE_COUNTERS && ENABLE_COUNTERS64; - instr_rdinstr <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000001000000010) && ENABLE_COUNTERS; - instr_rdinstrh <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000001000000010) && ENABLE_COUNTERS && ENABLE_COUNTERS64; - - instr_ecall_ebreak <= ((mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]) || - (COMPRESSED_ISA && mem_rdata_q[15:0] == 16'h9002)); - - instr_getq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS; - instr_setq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000001 && ENABLE_IRQ && ENABLE_IRQ_QREGS; - instr_maskirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000011 && ENABLE_IRQ; - instr_timer <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000101 && ENABLE_IRQ && ENABLE_IRQ_TIMER; - - is_slli_srli_srai <= is_alu_reg_imm && |{ - mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000, - mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000, - mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000 - }; - - is_jalr_addi_slti_sltiu_xori_ori_andi <= instr_jalr || is_alu_reg_imm && |{ - mem_rdata_q[14:12] == 3'b000, - mem_rdata_q[14:12] == 3'b010, - mem_rdata_q[14:12] == 3'b011, - mem_rdata_q[14:12] == 3'b100, - mem_rdata_q[14:12] == 3'b110, - mem_rdata_q[14:12] == 3'b111 - }; - - is_sll_srl_sra <= is_alu_reg_reg && |{ - mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000, - mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000, - mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000 - }; - - is_lui_auipc_jal_jalr_addi_add_sub <= 0; - is_compare <= 0; - - (* parallel_case *) - case (1'b1) - instr_jal: - decoded_imm <= decoded_imm_j; - |{instr_lui, instr_auipc}: - decoded_imm <= mem_rdata_q[31:12] << 12; - |{instr_jalr, is_lb_lh_lw_lbu_lhu, is_alu_reg_imm}: - decoded_imm <= $signed(mem_rdata_q[31:20]); - is_beq_bne_blt_bge_bltu_bgeu: - decoded_imm <= $signed({mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8], 1'b0}); - is_sb_sh_sw: - decoded_imm <= $signed({mem_rdata_q[31:25], mem_rdata_q[11:7]}); - default: - decoded_imm <= 1'bx; - endcase - end - - if (!resetn) begin - is_beq_bne_blt_bge_bltu_bgeu <= 0; - is_compare <= 0; - - instr_beq <= 0; - instr_bne <= 0; - instr_blt <= 0; - instr_bge <= 0; - instr_bltu <= 0; - instr_bgeu <= 0; - - instr_addi <= 0; - instr_slti <= 0; - instr_sltiu <= 0; - instr_xori <= 0; - instr_ori <= 0; - instr_andi <= 0; - - instr_add <= 0; - instr_sub <= 0; - instr_sll <= 0; - instr_slt <= 0; - instr_sltu <= 0; - instr_xor <= 0; - instr_srl <= 0; - instr_sra <= 0; - instr_or <= 0; - instr_and <= 0; - end - end - - - // Main State Machine - - localparam cpu_state_trap = 8'b10000000; - localparam cpu_state_fetch = 8'b01000000; - localparam cpu_state_ld_rs1 = 8'b00100000; - localparam cpu_state_ld_rs2 = 8'b00010000; - localparam cpu_state_exec = 8'b00001000; - localparam cpu_state_shift = 8'b00000100; - localparam cpu_state_stmem = 8'b00000010; - localparam cpu_state_ldmem = 8'b00000001; - - reg [7:0] cpu_state; - reg [1:0] irq_state; - - `FORMAL_KEEP reg [127:0] dbg_ascii_state; - - always @* begin - dbg_ascii_state = ""; - if (cpu_state == cpu_state_trap) dbg_ascii_state = "trap"; - if (cpu_state == cpu_state_fetch) dbg_ascii_state = "fetch"; - if (cpu_state == cpu_state_ld_rs1) dbg_ascii_state = "ld_rs1"; - if (cpu_state == cpu_state_ld_rs2) dbg_ascii_state = "ld_rs2"; - if (cpu_state == cpu_state_exec) dbg_ascii_state = "exec"; - if (cpu_state == cpu_state_shift) dbg_ascii_state = "shift"; - if (cpu_state == cpu_state_stmem) dbg_ascii_state = "stmem"; - if (cpu_state == cpu_state_ldmem) dbg_ascii_state = "ldmem"; - end - - reg set_mem_do_rinst; - reg set_mem_do_rdata; - reg set_mem_do_wdata; - - reg latched_store; - reg latched_stalu; - reg latched_branch; - reg latched_compr; - reg latched_trace; - reg latched_is_lu; - reg latched_is_lh; - reg latched_is_lb; - reg [regindex_bits-1:0] latched_rd; - - reg [31:0] current_pc; - assign next_pc = latched_store && latched_branch ? reg_out & ~1 : reg_next_pc; - - reg [3:0] pcpi_timeout_counter; - reg pcpi_timeout; - - reg [31:0] next_irq_pending; - reg do_waitirq; - - reg [31:0] alu_out, alu_out_q; - reg alu_out_0, alu_out_0_q; - reg alu_wait, alu_wait_2; - - reg [31:0] alu_add_sub; - reg [31:0] alu_shl, alu_shr; - reg alu_eq, alu_ltu, alu_lts; - - generate if (TWO_CYCLE_ALU) begin - always @(posedge clk) begin - alu_add_sub <= instr_sub ? reg_op1 - reg_op2 : reg_op1 + reg_op2; - alu_eq <= reg_op1 == reg_op2; - alu_lts <= $signed(reg_op1) < $signed(reg_op2); - alu_ltu <= reg_op1 < reg_op2; - alu_shl <= reg_op1 << reg_op2[4:0]; - alu_shr <= $signed({instr_sra || instr_srai ? reg_op1[31] : 1'b0, reg_op1}) >>> reg_op2[4:0]; - end - end else begin - always @* begin - alu_add_sub = instr_sub ? reg_op1 - reg_op2 : reg_op1 + reg_op2; - alu_eq = reg_op1 == reg_op2; - alu_lts = $signed(reg_op1) < $signed(reg_op2); - alu_ltu = reg_op1 < reg_op2; - alu_shl = reg_op1 << reg_op2[4:0]; - alu_shr = $signed({instr_sra || instr_srai ? reg_op1[31] : 1'b0, reg_op1}) >>> reg_op2[4:0]; - end - end endgenerate - - always @* begin - alu_out_0 = 'bx; - (* parallel_case, full_case *) - case (1'b1) - instr_beq: - alu_out_0 = alu_eq; - instr_bne: - alu_out_0 = !alu_eq; - instr_bge: - alu_out_0 = !alu_lts; - instr_bgeu: - alu_out_0 = !alu_ltu; - is_slti_blt_slt && (!TWO_CYCLE_COMPARE || !{instr_beq,instr_bne,instr_bge,instr_bgeu}): - alu_out_0 = alu_lts; - is_sltiu_bltu_sltu && (!TWO_CYCLE_COMPARE || !{instr_beq,instr_bne,instr_bge,instr_bgeu}): - alu_out_0 = alu_ltu; - endcase - - alu_out = 'bx; - (* parallel_case, full_case *) - case (1'b1) - is_lui_auipc_jal_jalr_addi_add_sub: - alu_out = alu_add_sub; - is_compare: - alu_out = alu_out_0; - instr_xori || instr_xor: - alu_out = reg_op1 ^ reg_op2; - instr_ori || instr_or: - alu_out = reg_op1 | reg_op2; - instr_andi || instr_and: - alu_out = reg_op1 & reg_op2; - BARREL_SHIFTER && (instr_sll || instr_slli): - alu_out = alu_shl; - BARREL_SHIFTER && (instr_srl || instr_srli || instr_sra || instr_srai): - alu_out = alu_shr; - endcase - -`ifdef RISCV_FORMAL_BLACKBOX_ALU - alu_out_0 = $anyseq; - alu_out = $anyseq; -`endif - end - - reg clear_prefetched_high_word_q; - always @(posedge clk) clear_prefetched_high_word_q <= clear_prefetched_high_word; - - always @* begin - clear_prefetched_high_word = clear_prefetched_high_word_q; - if (!prefetched_high_word) - clear_prefetched_high_word = 0; - if (latched_branch || irq_state || !resetn) - clear_prefetched_high_word = COMPRESSED_ISA; - end - - reg cpuregs_write; - reg [31:0] cpuregs_wrdata; - reg [31:0] cpuregs_rs1; - reg [31:0] cpuregs_rs2; - reg [regindex_bits-1:0] decoded_rs; - - always @* begin - cpuregs_write = 0; - cpuregs_wrdata = 'bx; - - if (cpu_state == cpu_state_fetch) begin - (* parallel_case *) - case (1'b1) - latched_branch: begin - cpuregs_wrdata = reg_pc + (latched_compr ? 2 : 4); - cpuregs_write = 1; - end - latched_store && !latched_branch: begin - cpuregs_wrdata = latched_stalu ? alu_out_q : reg_out; - cpuregs_write = 1; - end - ENABLE_IRQ && irq_state[0]: begin - cpuregs_wrdata = reg_next_pc | latched_compr; - cpuregs_write = 1; - end - ENABLE_IRQ && irq_state[1]: begin - cpuregs_wrdata = irq_pending & ~irq_mask; - cpuregs_write = 1; - end - endcase - end - end - -`ifndef PICORV32_REGS - always @(posedge clk) begin - if (resetn && cpuregs_write && latched_rd) -`ifdef PICORV32_TESTBUG_001 - cpuregs[latched_rd ^ 1] <= cpuregs_wrdata; -`elsif PICORV32_TESTBUG_002 - cpuregs[latched_rd] <= cpuregs_wrdata ^ 1; -`else - cpuregs[latched_rd] <= cpuregs_wrdata; -`endif - end - - always @* begin - decoded_rs = 'bx; - if (ENABLE_REGS_DUALPORT) begin -`ifndef RISCV_FORMAL_BLACKBOX_REGS - cpuregs_rs1 = decoded_rs1 ? cpuregs[decoded_rs1] : 0; - cpuregs_rs2 = decoded_rs2 ? cpuregs[decoded_rs2] : 0; -`else - cpuregs_rs1 = decoded_rs1 ? $anyseq : 0; - cpuregs_rs2 = decoded_rs2 ? $anyseq : 0; -`endif - end else begin - decoded_rs = (cpu_state == cpu_state_ld_rs2) ? decoded_rs2 : decoded_rs1; -`ifndef RISCV_FORMAL_BLACKBOX_REGS - cpuregs_rs1 = decoded_rs ? cpuregs[decoded_rs] : 0; -`else - cpuregs_rs1 = decoded_rs ? $anyseq : 0; -`endif - cpuregs_rs2 = cpuregs_rs1; - end - end -`else - wire[31:0] cpuregs_rdata1; - wire[31:0] cpuregs_rdata2; - - wire [5:0] cpuregs_waddr = latched_rd; - wire [5:0] cpuregs_raddr1 = ENABLE_REGS_DUALPORT ? decoded_rs1 : decoded_rs; - wire [5:0] cpuregs_raddr2 = ENABLE_REGS_DUALPORT ? decoded_rs2 : 0; - - `PICORV32_REGS cpuregs ( - .clk(clk), - .wen(resetn && cpuregs_write && latched_rd), - .waddr(cpuregs_waddr), - .raddr1(cpuregs_raddr1), - .raddr2(cpuregs_raddr2), - .wdata(cpuregs_wrdata), - .rdata1(cpuregs_rdata1), - .rdata2(cpuregs_rdata2) - ); - - always @* begin - decoded_rs = 'bx; - if (ENABLE_REGS_DUALPORT) begin - cpuregs_rs1 = decoded_rs1 ? cpuregs_rdata1 : 0; - cpuregs_rs2 = decoded_rs2 ? cpuregs_rdata2 : 0; - end else begin - decoded_rs = (cpu_state == cpu_state_ld_rs2) ? decoded_rs2 : decoded_rs1; - cpuregs_rs1 = decoded_rs ? cpuregs_rdata1 : 0; - cpuregs_rs2 = cpuregs_rs1; - end - end -`endif - - assign launch_next_insn = cpu_state == cpu_state_fetch && decoder_trigger && (!ENABLE_IRQ || irq_delay || irq_active || !(irq_pending & ~irq_mask)); - - always @(posedge clk) begin - trap <= 0; - reg_sh <= 'bx; - reg_out <= 'bx; - set_mem_do_rinst = 0; - set_mem_do_rdata = 0; - set_mem_do_wdata = 0; - - alu_out_0_q <= alu_out_0; - alu_out_q <= alu_out; - - alu_wait <= 0; - alu_wait_2 <= 0; - - if (launch_next_insn) begin - dbg_rs1val <= 'bx; - dbg_rs2val <= 'bx; - dbg_rs1val_valid <= 0; - dbg_rs2val_valid <= 0; - end - - if (WITH_PCPI && CATCH_ILLINSN) begin - if (resetn && pcpi_valid && !pcpi_int_wait) begin - if (pcpi_timeout_counter) - pcpi_timeout_counter <= pcpi_timeout_counter - 1; - end else - pcpi_timeout_counter <= ~0; - pcpi_timeout <= !pcpi_timeout_counter; - end - - if (ENABLE_COUNTERS) begin - count_cycle <= resetn ? count_cycle + 1 : 0; - if (!ENABLE_COUNTERS64) count_cycle[63:32] <= 0; - end else begin - count_cycle <= 'bx; - count_instr <= 'bx; - end - - next_irq_pending = ENABLE_IRQ ? irq_pending & LATCHED_IRQ : 'bx; - - if (ENABLE_IRQ && ENABLE_IRQ_TIMER && timer) begin - timer <= timer - 1; - end - - decoder_trigger <= mem_do_rinst && mem_done; - decoder_trigger_q <= decoder_trigger; - decoder_pseudo_trigger <= 0; - decoder_pseudo_trigger_q <= decoder_pseudo_trigger; - do_waitirq <= 0; - - trace_valid <= 0; - - if (!ENABLE_TRACE) - trace_data <= 'bx; - - if (!resetn) begin - reg_pc <= PROGADDR_RESET; - reg_next_pc <= PROGADDR_RESET; - if (ENABLE_COUNTERS) - count_instr <= 0; - latched_store <= 0; - latched_stalu <= 0; - latched_branch <= 0; - latched_trace <= 0; - latched_is_lu <= 0; - latched_is_lh <= 0; - latched_is_lb <= 0; - pcpi_valid <= 0; - pcpi_timeout <= 0; - irq_active <= 0; - irq_delay <= 0; - irq_mask <= ~0; - next_irq_pending = 0; - irq_state <= 0; - eoi <= 0; - timer <= 0; - if (~STACKADDR) begin - latched_store <= 1; - latched_rd <= 2; - reg_out <= STACKADDR; - end - cpu_state <= cpu_state_fetch; - end else - (* parallel_case, full_case *) - case (cpu_state) - cpu_state_trap: begin - trap <= 1; - end - - cpu_state_fetch: begin - mem_do_rinst <= !decoder_trigger && !do_waitirq; - mem_wordsize <= 0; - - current_pc = reg_next_pc; - - (* parallel_case *) - case (1'b1) - latched_branch: begin - current_pc = latched_store ? (latched_stalu ? alu_out_q : reg_out) & ~1 : reg_next_pc; - `debug($display("ST_RD: %2d 0x%08x, BRANCH 0x%08x", latched_rd, reg_pc + (latched_compr ? 2 : 4), current_pc);) - end - latched_store && !latched_branch: begin - `debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out);) - end - ENABLE_IRQ && irq_state[0]: begin - current_pc = PROGADDR_IRQ; - irq_active <= 1; - mem_do_rinst <= 1; - end - ENABLE_IRQ && irq_state[1]: begin - eoi <= irq_pending & ~irq_mask; - next_irq_pending = next_irq_pending & irq_mask; - end - endcase - - if (ENABLE_TRACE && latched_trace) begin - latched_trace <= 0; - trace_valid <= 1; - if (latched_branch) - trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_BRANCH | (current_pc & 32'hfffffffe); - else - trace_data <= (irq_active ? TRACE_IRQ : 0) | (latched_stalu ? alu_out_q : reg_out); - end - - reg_pc <= current_pc; - reg_next_pc <= current_pc; - - latched_store <= 0; - latched_stalu <= 0; - latched_branch <= 0; - latched_is_lu <= 0; - latched_is_lh <= 0; - latched_is_lb <= 0; - latched_rd <= decoded_rd; - latched_compr <= compressed_instr; - - if (ENABLE_IRQ && ((decoder_trigger && !irq_active && !irq_delay && |(irq_pending & ~irq_mask)) || irq_state)) begin - irq_state <= - irq_state == 2'b00 ? 2'b01 : - irq_state == 2'b01 ? 2'b10 : 2'b00; - latched_compr <= latched_compr; - if (ENABLE_IRQ_QREGS) - latched_rd <= irqregs_offset | irq_state[0]; - else - latched_rd <= irq_state[0] ? 4 : 3; - end else - if (ENABLE_IRQ && (decoder_trigger || do_waitirq) && instr_waitirq) begin - if (irq_pending) begin - latched_store <= 1; - reg_out <= irq_pending; - reg_next_pc <= current_pc + (compressed_instr ? 2 : 4); - mem_do_rinst <= 1; - end else - do_waitirq <= 1; - end else - if (decoder_trigger) begin - `debug($display("-- %-0t", $time);) - irq_delay <= irq_active; - reg_next_pc <= current_pc + (compressed_instr ? 2 : 4); - if (ENABLE_TRACE) - latched_trace <= 1; - if (ENABLE_COUNTERS) begin - count_instr <= count_instr + 1; - if (!ENABLE_COUNTERS64) count_instr[63:32] <= 0; - end - if (instr_jal) begin - mem_do_rinst <= 1; - reg_next_pc <= current_pc + decoded_imm_j; - latched_branch <= 1; - end else begin - mem_do_rinst <= 0; - mem_do_prefetch <= !instr_jalr && !instr_retirq; - cpu_state <= cpu_state_ld_rs1; - end - end - end - - cpu_state_ld_rs1: begin - reg_op1 <= 'bx; - reg_op2 <= 'bx; - - (* parallel_case *) - case (1'b1) - (CATCH_ILLINSN || WITH_PCPI) && instr_trap: begin - if (WITH_PCPI) begin - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - reg_op1 <= cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - if (ENABLE_REGS_DUALPORT) begin - pcpi_valid <= 1; - `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);) - reg_sh <= cpuregs_rs2; - reg_op2 <= cpuregs_rs2; - dbg_rs2val <= cpuregs_rs2; - dbg_rs2val_valid <= 1; - if (pcpi_int_ready) begin - mem_do_rinst <= 1; - pcpi_valid <= 0; - reg_out <= pcpi_int_rd; - latched_store <= pcpi_int_wr; - cpu_state <= cpu_state_fetch; - end else - if (CATCH_ILLINSN && (pcpi_timeout || instr_ecall_ebreak)) begin - pcpi_valid <= 0; - `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) - if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin - next_irq_pending[irq_ebreak] = 1; - cpu_state <= cpu_state_fetch; - end else - cpu_state <= cpu_state_trap; - end - end else begin - cpu_state <= cpu_state_ld_rs2; - end - end else begin - `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) - if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin - next_irq_pending[irq_ebreak] = 1; - cpu_state <= cpu_state_fetch; - end else - cpu_state <= cpu_state_trap; - end - end - ENABLE_COUNTERS && is_rdcycle_rdcycleh_rdinstr_rdinstrh: begin - (* parallel_case, full_case *) - case (1'b1) - instr_rdcycle: - reg_out <= count_cycle[31:0]; - instr_rdcycleh && ENABLE_COUNTERS64: - reg_out <= count_cycle[63:32]; - instr_rdinstr: - reg_out <= count_instr[31:0]; - instr_rdinstrh && ENABLE_COUNTERS64: - reg_out <= count_instr[63:32]; - endcase - latched_store <= 1; - cpu_state <= cpu_state_fetch; - end - is_lui_auipc_jal: begin - reg_op1 <= instr_lui ? 0 : reg_pc; - reg_op2 <= decoded_imm; - if (TWO_CYCLE_ALU) - alu_wait <= 1; - else - mem_do_rinst <= mem_do_prefetch; - cpu_state <= cpu_state_exec; - end - ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_getq: begin - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - reg_out <= cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - latched_store <= 1; - cpu_state <= cpu_state_fetch; - end - ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_setq: begin - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - reg_out <= cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - latched_rd <= latched_rd | irqregs_offset; - latched_store <= 1; - cpu_state <= cpu_state_fetch; - end - ENABLE_IRQ && instr_retirq: begin - eoi <= 0; - irq_active <= 0; - latched_branch <= 1; - latched_store <= 1; - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - reg_out <= CATCH_MISALIGN ? (cpuregs_rs1 & 32'h fffffffe) : cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - cpu_state <= cpu_state_fetch; - end - ENABLE_IRQ && instr_maskirq: begin - latched_store <= 1; - reg_out <= irq_mask; - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - irq_mask <= cpuregs_rs1 | MASKED_IRQ; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - cpu_state <= cpu_state_fetch; - end - ENABLE_IRQ && ENABLE_IRQ_TIMER && instr_timer: begin - latched_store <= 1; - reg_out <= timer; - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - timer <= cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - cpu_state <= cpu_state_fetch; - end - is_lb_lh_lw_lbu_lhu && !instr_trap: begin - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - reg_op1 <= cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - cpu_state <= cpu_state_ldmem; - mem_do_rinst <= 1; - end - is_slli_srli_srai && !BARREL_SHIFTER: begin - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - reg_op1 <= cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - reg_sh <= decoded_rs2; - cpu_state <= cpu_state_shift; - end - is_jalr_addi_slti_sltiu_xori_ori_andi, is_slli_srli_srai && BARREL_SHIFTER: begin - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - reg_op1 <= cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - reg_op2 <= is_slli_srli_srai && BARREL_SHIFTER ? decoded_rs2 : decoded_imm; - if (TWO_CYCLE_ALU) - alu_wait <= 1; - else - mem_do_rinst <= mem_do_prefetch; - cpu_state <= cpu_state_exec; - end - default: begin - `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) - reg_op1 <= cpuregs_rs1; - dbg_rs1val <= cpuregs_rs1; - dbg_rs1val_valid <= 1; - if (ENABLE_REGS_DUALPORT) begin - `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);) - reg_sh <= cpuregs_rs2; - reg_op2 <= cpuregs_rs2; - dbg_rs2val <= cpuregs_rs2; - dbg_rs2val_valid <= 1; - (* parallel_case *) - case (1'b1) - is_sb_sh_sw: begin - cpu_state <= cpu_state_stmem; - mem_do_rinst <= 1; - end - is_sll_srl_sra && !BARREL_SHIFTER: begin - cpu_state <= cpu_state_shift; - end - default: begin - if (TWO_CYCLE_ALU || (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu)) begin - alu_wait_2 <= TWO_CYCLE_ALU && (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu); - alu_wait <= 1; - end else - mem_do_rinst <= mem_do_prefetch; - cpu_state <= cpu_state_exec; - end - endcase - end else - cpu_state <= cpu_state_ld_rs2; - end - endcase - end - - cpu_state_ld_rs2: begin - `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);) - reg_sh <= cpuregs_rs2; - reg_op2 <= cpuregs_rs2; - dbg_rs2val <= cpuregs_rs2; - dbg_rs2val_valid <= 1; - - (* parallel_case *) - case (1'b1) - WITH_PCPI && instr_trap: begin - pcpi_valid <= 1; - if (pcpi_int_ready) begin - mem_do_rinst <= 1; - pcpi_valid <= 0; - reg_out <= pcpi_int_rd; - latched_store <= pcpi_int_wr; - cpu_state <= cpu_state_fetch; - end else - if (CATCH_ILLINSN && (pcpi_timeout || instr_ecall_ebreak)) begin - pcpi_valid <= 0; - `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) - if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin - next_irq_pending[irq_ebreak] = 1; - cpu_state <= cpu_state_fetch; - end else - cpu_state <= cpu_state_trap; - end - end - is_sb_sh_sw: begin - cpu_state <= cpu_state_stmem; - mem_do_rinst <= 1; - end - is_sll_srl_sra && !BARREL_SHIFTER: begin - cpu_state <= cpu_state_shift; - end - default: begin - if (TWO_CYCLE_ALU || (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu)) begin - alu_wait_2 <= TWO_CYCLE_ALU && (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu); - alu_wait <= 1; - end else - mem_do_rinst <= mem_do_prefetch; - cpu_state <= cpu_state_exec; - end - endcase - end - - cpu_state_exec: begin - reg_out <= reg_pc + decoded_imm; - if ((TWO_CYCLE_ALU || TWO_CYCLE_COMPARE) && (alu_wait || alu_wait_2)) begin - mem_do_rinst <= mem_do_prefetch && !alu_wait_2; - alu_wait <= alu_wait_2; - end else - if (is_beq_bne_blt_bge_bltu_bgeu) begin - latched_rd <= 0; - latched_store <= TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0; - latched_branch <= TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0; - if (mem_done) - cpu_state <= cpu_state_fetch; - if (TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0) begin - decoder_trigger <= 0; - set_mem_do_rinst = 1; - end - end else begin - latched_branch <= instr_jalr; - latched_store <= 1; - latched_stalu <= 1; - cpu_state <= cpu_state_fetch; - end - end - - cpu_state_shift: begin - latched_store <= 1; - if (reg_sh == 0) begin - reg_out <= reg_op1; - mem_do_rinst <= mem_do_prefetch; - cpu_state <= cpu_state_fetch; - end else if (TWO_STAGE_SHIFT && reg_sh >= 4) begin - (* parallel_case, full_case *) - case (1'b1) - instr_slli || instr_sll: reg_op1 <= reg_op1 << 4; - instr_srli || instr_srl: reg_op1 <= reg_op1 >> 4; - instr_srai || instr_sra: reg_op1 <= $signed(reg_op1) >>> 4; - endcase - reg_sh <= reg_sh - 4; - end else begin - (* parallel_case, full_case *) - case (1'b1) - instr_slli || instr_sll: reg_op1 <= reg_op1 << 1; - instr_srli || instr_srl: reg_op1 <= reg_op1 >> 1; - instr_srai || instr_sra: reg_op1 <= $signed(reg_op1) >>> 1; - endcase - reg_sh <= reg_sh - 1; - end - end - - cpu_state_stmem: begin - if (ENABLE_TRACE) - reg_out <= reg_op2; - if (!mem_do_prefetch || mem_done) begin - if (!mem_do_wdata) begin - (* parallel_case, full_case *) - case (1'b1) - instr_sb: mem_wordsize <= 2; - instr_sh: mem_wordsize <= 1; - instr_sw: mem_wordsize <= 0; - endcase - if (ENABLE_TRACE) begin - trace_valid <= 1; - trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff); - end - reg_op1 <= reg_op1 + decoded_imm; - set_mem_do_wdata = 1; - end - if (!mem_do_prefetch && mem_done) begin - cpu_state <= cpu_state_fetch; - decoder_trigger <= 1; - decoder_pseudo_trigger <= 1; - end - end - end - - cpu_state_ldmem: begin - latched_store <= 1; - if (!mem_do_prefetch || mem_done) begin - if (!mem_do_rdata) begin - (* parallel_case, full_case *) - case (1'b1) - instr_lb || instr_lbu: mem_wordsize <= 2; - instr_lh || instr_lhu: mem_wordsize <= 1; - instr_lw: mem_wordsize <= 0; - endcase - latched_is_lu <= is_lbu_lhu_lw; - latched_is_lh <= instr_lh; - latched_is_lb <= instr_lb; - if (ENABLE_TRACE) begin - trace_valid <= 1; - trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff); - end - reg_op1 <= reg_op1 + decoded_imm; - set_mem_do_rdata = 1; - end - if (!mem_do_prefetch && mem_done) begin - (* parallel_case, full_case *) - case (1'b1) - latched_is_lu: reg_out <= mem_rdata_word; - latched_is_lh: reg_out <= $signed(mem_rdata_word[15:0]); - latched_is_lb: reg_out <= $signed(mem_rdata_word[7:0]); - endcase - decoder_trigger <= 1; - decoder_pseudo_trigger <= 1; - cpu_state <= cpu_state_fetch; - end - end - end - endcase - - if (ENABLE_IRQ) begin - next_irq_pending = next_irq_pending | irq; - if(ENABLE_IRQ_TIMER && timer) - if (timer - 1 == 0) - next_irq_pending[irq_timer] = 1; - end - - if (CATCH_MISALIGN && resetn && (mem_do_rdata || mem_do_wdata)) begin - if (mem_wordsize == 0 && reg_op1[1:0] != 0) begin - `debug($display("MISALIGNED WORD: 0x%08x", reg_op1);) - if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin - next_irq_pending[irq_buserror] = 1; - end else - cpu_state <= cpu_state_trap; - end - if (mem_wordsize == 1 && reg_op1[0] != 0) begin - `debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);) - if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin - next_irq_pending[irq_buserror] = 1; - end else - cpu_state <= cpu_state_trap; - end - end - if (CATCH_MISALIGN && resetn && mem_do_rinst && (COMPRESSED_ISA ? reg_pc[0] : |reg_pc[1:0])) begin - `debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);) - if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin - next_irq_pending[irq_buserror] = 1; - end else - cpu_state <= cpu_state_trap; - end - if (!CATCH_ILLINSN && decoder_trigger_q && !decoder_pseudo_trigger_q && instr_ecall_ebreak) begin - cpu_state <= cpu_state_trap; - end - - if (!resetn || mem_done) begin - mem_do_prefetch <= 0; - mem_do_rinst <= 0; - mem_do_rdata <= 0; - mem_do_wdata <= 0; - end - - if (set_mem_do_rinst) - mem_do_rinst <= 1; - if (set_mem_do_rdata) - mem_do_rdata <= 1; - if (set_mem_do_wdata) - mem_do_wdata <= 1; - - irq_pending <= next_irq_pending & ~MASKED_IRQ; - - if (!CATCH_MISALIGN) begin - if (COMPRESSED_ISA) begin - reg_pc[0] <= 0; - reg_next_pc[0] <= 0; - end else begin - reg_pc[1:0] <= 0; - reg_next_pc[1:0] <= 0; - end - end - current_pc = 'bx; - end - -`ifdef RISCV_FORMAL - reg dbg_irq_call; - reg dbg_irq_enter; - reg [31:0] dbg_irq_ret; - always @(posedge clk) begin - rvfi_valid <= resetn && (launch_next_insn || trap) && dbg_valid_insn; - rvfi_order <= resetn ? rvfi_order + rvfi_valid : 0; - - rvfi_insn <= dbg_insn_opcode; - rvfi_rs1_addr <= dbg_rs1val_valid ? dbg_insn_rs1 : 0; - rvfi_rs2_addr <= dbg_rs2val_valid ? dbg_insn_rs2 : 0; - rvfi_pc_rdata <= dbg_insn_addr; - rvfi_rs1_rdata <= dbg_rs1val_valid ? dbg_rs1val : 0; - rvfi_rs2_rdata <= dbg_rs2val_valid ? dbg_rs2val : 0; - rvfi_trap <= trap; - rvfi_halt <= trap; - rvfi_intr <= dbg_irq_enter; - rvfi_mode <= 3; - rvfi_ixl <= 1; - - if (!resetn) begin - dbg_irq_call <= 0; - dbg_irq_enter <= 0; - end else - if (rvfi_valid) begin - dbg_irq_call <= 0; - dbg_irq_enter <= dbg_irq_call; - end else - if (irq_state == 1) begin - dbg_irq_call <= 1; - dbg_irq_ret <= next_pc; - end - - if (!resetn) begin - rvfi_rd_addr <= 0; - rvfi_rd_wdata <= 0; - end else - if (cpuregs_write && !irq_state) begin -`ifdef PICORV32_TESTBUG_003 - rvfi_rd_addr <= latched_rd ^ 1; -`else - rvfi_rd_addr <= latched_rd; -`endif -`ifdef PICORV32_TESTBUG_004 - rvfi_rd_wdata <= latched_rd ? cpuregs_wrdata ^ 1 : 0; -`else - rvfi_rd_wdata <= latched_rd ? cpuregs_wrdata : 0; -`endif - end else - if (rvfi_valid) begin - rvfi_rd_addr <= 0; - rvfi_rd_wdata <= 0; - end - - casez (dbg_insn_opcode) - 32'b 0000000_?????_000??_???_?????_0001011: begin // getq - rvfi_rs1_addr <= 0; - rvfi_rs1_rdata <= 0; - end - 32'b 0000001_?????_?????_???_000??_0001011: begin // setq - rvfi_rd_addr <= 0; - rvfi_rd_wdata <= 0; - end - 32'b 0000010_?????_00000_???_00000_0001011: begin // retirq - rvfi_rs1_addr <= 0; - rvfi_rs1_rdata <= 0; - end - endcase - - if (!dbg_irq_call) begin - if (dbg_mem_instr) begin - rvfi_mem_addr <= 0; - rvfi_mem_rmask <= 0; - rvfi_mem_wmask <= 0; - rvfi_mem_rdata <= 0; - rvfi_mem_wdata <= 0; - end else - if (dbg_mem_valid && dbg_mem_ready) begin - rvfi_mem_addr <= dbg_mem_addr; - rvfi_mem_rmask <= dbg_mem_wstrb ? 0 : ~0; - rvfi_mem_wmask <= dbg_mem_wstrb; - rvfi_mem_rdata <= dbg_mem_rdata; - rvfi_mem_wdata <= dbg_mem_wdata; - end - end - end - - always @* begin -`ifdef PICORV32_TESTBUG_005 - rvfi_pc_wdata = (dbg_irq_call ? dbg_irq_ret : dbg_insn_addr) ^ 4; -`else - rvfi_pc_wdata = dbg_irq_call ? dbg_irq_ret : dbg_insn_addr; -`endif - - rvfi_csr_mcycle_rmask = 0; - rvfi_csr_mcycle_wmask = 0; - rvfi_csr_mcycle_rdata = 0; - rvfi_csr_mcycle_wdata = 0; - - rvfi_csr_minstret_rmask = 0; - rvfi_csr_minstret_wmask = 0; - rvfi_csr_minstret_rdata = 0; - rvfi_csr_minstret_wdata = 0; - - if (rvfi_valid && rvfi_insn[6:0] == 7'b 1110011 && rvfi_insn[13:12] == 3'b010) begin - if (rvfi_insn[31:20] == 12'h C00) begin - rvfi_csr_mcycle_rmask = 64'h 0000_0000_FFFF_FFFF; - rvfi_csr_mcycle_rdata = {32'h 0000_0000, rvfi_rd_wdata}; - end - if (rvfi_insn[31:20] == 12'h C80) begin - rvfi_csr_mcycle_rmask = 64'h FFFF_FFFF_0000_0000; - rvfi_csr_mcycle_rdata = {rvfi_rd_wdata, 32'h 0000_0000}; - end - if (rvfi_insn[31:20] == 12'h C02) begin - rvfi_csr_minstret_rmask = 64'h 0000_0000_FFFF_FFFF; - rvfi_csr_minstret_rdata = {32'h 0000_0000, rvfi_rd_wdata}; - end - if (rvfi_insn[31:20] == 12'h C82) begin - rvfi_csr_minstret_rmask = 64'h FFFF_FFFF_0000_0000; - rvfi_csr_minstret_rdata = {rvfi_rd_wdata, 32'h 0000_0000}; - end - end - end -`endif - - // Formal Verification -`ifdef FORMAL - reg [3:0] last_mem_nowait; - always @(posedge clk) - last_mem_nowait <= {last_mem_nowait, mem_ready || !mem_valid}; - - // stall the memory interface for max 4 cycles - restrict property (|last_mem_nowait || mem_ready || !mem_valid); - - // resetn low in first cycle, after that resetn high - restrict property (resetn != $initstate); - - // this just makes it much easier to read traces. uncomment as needed. - // assume property (mem_valid || !mem_ready); - - reg ok; - always @* begin - if (resetn) begin - // instruction fetches are read-only - if (mem_valid && mem_instr) - assert (mem_wstrb == 0); - - // cpu_state must be valid - ok = 0; - if (cpu_state == cpu_state_trap) ok = 1; - if (cpu_state == cpu_state_fetch) ok = 1; - if (cpu_state == cpu_state_ld_rs1) ok = 1; - if (cpu_state == cpu_state_ld_rs2) ok = !ENABLE_REGS_DUALPORT; - if (cpu_state == cpu_state_exec) ok = 1; - if (cpu_state == cpu_state_shift) ok = 1; - if (cpu_state == cpu_state_stmem) ok = 1; - if (cpu_state == cpu_state_ldmem) ok = 1; - assert (ok); - end - end - - reg last_mem_la_read = 0; - reg last_mem_la_write = 0; - reg [31:0] last_mem_la_addr; - reg [31:0] last_mem_la_wdata; - reg [3:0] last_mem_la_wstrb = 0; - - always @(posedge clk) begin - last_mem_la_read <= mem_la_read; - last_mem_la_write <= mem_la_write; - last_mem_la_addr <= mem_la_addr; - last_mem_la_wdata <= mem_la_wdata; - last_mem_la_wstrb <= mem_la_wstrb; - - if (last_mem_la_read) begin - assert(mem_valid); - assert(mem_addr == last_mem_la_addr); - assert(mem_wstrb == 0); - end - if (last_mem_la_write) begin - assert(mem_valid); - assert(mem_addr == last_mem_la_addr); - assert(mem_wdata == last_mem_la_wdata); - assert(mem_wstrb == last_mem_la_wstrb); - end - if (mem_la_read || mem_la_write) begin - assert(!mem_valid || mem_ready); - end - end -`endif -endmodule - -// This is a simple example implementation of PICORV32_REGS. -// Use the PICORV32_REGS mechanism if you want to use custom -// memory resources to implement the processor register file. -// Note that your implementation must match the requirements of -// the PicoRV32 configuration. (e.g. QREGS, etc) -module picorv32_regs ( - input clk, wen, - input [5:0] waddr, - input [5:0] raddr1, - input [5:0] raddr2, - input [31:0] wdata, - output [31:0] rdata1, - output [31:0] rdata2 -); - reg [31:0] regs [0:30]; - - always @(posedge clk) - if (wen) regs[~waddr[4:0]] <= wdata; - - assign rdata1 = regs[~raddr1[4:0]]; - assign rdata2 = regs[~raddr2[4:0]]; -endmodule - - -/*************************************************************** - * picorv32_pcpi_mul - ***************************************************************/ - -module picorv32_pcpi_mul #( - parameter STEPS_AT_ONCE = 1, - parameter CARRY_CHAIN = 4 -) ( - input clk, resetn, - - input pcpi_valid, - input [31:0] pcpi_insn, - input [31:0] pcpi_rs1, - input [31:0] pcpi_rs2, - output reg pcpi_wr, - output reg [31:0] pcpi_rd, - output reg pcpi_wait, - output reg pcpi_ready -); - reg instr_mul, instr_mulh, instr_mulhsu, instr_mulhu; - wire instr_any_mul = |{instr_mul, instr_mulh, instr_mulhsu, instr_mulhu}; - wire instr_any_mulh = |{instr_mulh, instr_mulhsu, instr_mulhu}; - wire instr_rs1_signed = |{instr_mulh, instr_mulhsu}; - wire instr_rs2_signed = |{instr_mulh}; - - reg pcpi_wait_q; - wire mul_start = pcpi_wait && !pcpi_wait_q; - - always @(posedge clk) begin - instr_mul <= 0; - instr_mulh <= 0; - instr_mulhsu <= 0; - instr_mulhu <= 0; - - if (resetn && pcpi_valid && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001) begin - case (pcpi_insn[14:12]) - 3'b000: instr_mul <= 1; - 3'b001: instr_mulh <= 1; - 3'b010: instr_mulhsu <= 1; - 3'b011: instr_mulhu <= 1; - endcase - end - - pcpi_wait <= instr_any_mul; - pcpi_wait_q <= pcpi_wait; - end - - reg [63:0] rs1, rs2, rd, rdx; - reg [63:0] next_rs1, next_rs2, this_rs2; - reg [63:0] next_rd, next_rdx, next_rdt; - reg [6:0] mul_counter; - reg mul_waiting; - reg mul_finish; - integer i, j; - - // carry save accumulator - always @* begin - next_rd = rd; - next_rdx = rdx; - next_rs1 = rs1; - next_rs2 = rs2; - - for (i = 0; i < STEPS_AT_ONCE; i=i+1) begin - this_rs2 = next_rs1[0] ? next_rs2 : 0; - if (CARRY_CHAIN == 0) begin - next_rdt = next_rd ^ next_rdx ^ this_rs2; - next_rdx = ((next_rd & next_rdx) | (next_rd & this_rs2) | (next_rdx & this_rs2)) << 1; - next_rd = next_rdt; - end else begin - next_rdt = 0; - for (j = 0; j < 64; j = j + CARRY_CHAIN) - {next_rdt[j+CARRY_CHAIN-1], next_rd[j +: CARRY_CHAIN]} = - next_rd[j +: CARRY_CHAIN] + next_rdx[j +: CARRY_CHAIN] + this_rs2[j +: CARRY_CHAIN]; - next_rdx = next_rdt << 1; - end - next_rs1 = next_rs1 >> 1; - next_rs2 = next_rs2 << 1; - end - end - - always @(posedge clk) begin - mul_finish <= 0; - if (!resetn) begin - mul_waiting <= 1; - mul_counter <= 0; - end else - if (mul_waiting) begin - if (instr_rs1_signed) - rs1 <= $signed(pcpi_rs1); - else - rs1 <= $unsigned(pcpi_rs1); - - if (instr_rs2_signed) - rs2 <= $signed(pcpi_rs2); - else - rs2 <= $unsigned(pcpi_rs2); - - rd <= 0; - rdx <= 0; - mul_counter <= (instr_any_mulh ? 63 - STEPS_AT_ONCE : 31 - STEPS_AT_ONCE); - mul_waiting <= !mul_start; - end else begin - rd <= next_rd; - rdx <= next_rdx; - rs1 <= next_rs1; - rs2 <= next_rs2; - - mul_counter <= mul_counter - STEPS_AT_ONCE; - if (mul_counter[6]) begin - mul_finish <= 1; - mul_waiting <= 1; - end - end - end - - always @(posedge clk) begin - pcpi_wr <= 0; - pcpi_ready <= 0; - if (mul_finish && resetn) begin - pcpi_wr <= 1; - pcpi_ready <= 1; - pcpi_rd <= instr_any_mulh ? rd >> 32 : rd; - end - end -endmodule - -module picorv32_pcpi_fast_mul #( - parameter EXTRA_MUL_FFS = 0, - parameter EXTRA_INSN_FFS = 0, - parameter MUL_CLKGATE = 0 -) ( - input clk, resetn, - - input pcpi_valid, - input [31:0] pcpi_insn, - input [31:0] pcpi_rs1, - input [31:0] pcpi_rs2, - output pcpi_wr, - output [31:0] pcpi_rd, - output pcpi_wait, - output pcpi_ready -); - reg instr_mul, instr_mulh, instr_mulhsu, instr_mulhu; - wire instr_any_mul = |{instr_mul, instr_mulh, instr_mulhsu, instr_mulhu}; - wire instr_any_mulh = |{instr_mulh, instr_mulhsu, instr_mulhu}; - wire instr_rs1_signed = |{instr_mulh, instr_mulhsu}; - wire instr_rs2_signed = |{instr_mulh}; - - reg shift_out; - reg [3:0] active; - reg [32:0] rs1, rs2, rs1_q, rs2_q; - reg [63:0] rd, rd_q; - - wire pcpi_insn_valid = pcpi_valid && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001; - reg pcpi_insn_valid_q; - - always @* begin - instr_mul = 0; - instr_mulh = 0; - instr_mulhsu = 0; - instr_mulhu = 0; - - if (resetn && (EXTRA_INSN_FFS ? pcpi_insn_valid_q : pcpi_insn_valid)) begin - case (pcpi_insn[14:12]) - 3'b000: instr_mul = 1; - 3'b001: instr_mulh = 1; - 3'b010: instr_mulhsu = 1; - 3'b011: instr_mulhu = 1; - endcase - end - end - - always @(posedge clk) begin - pcpi_insn_valid_q <= pcpi_insn_valid; - if (!MUL_CLKGATE || active[0]) begin - rs1_q <= rs1; - rs2_q <= rs2; - end - if (!MUL_CLKGATE || active[1]) begin - rd <= $signed(EXTRA_MUL_FFS ? rs1_q : rs1) * $signed(EXTRA_MUL_FFS ? rs2_q : rs2); - end - if (!MUL_CLKGATE || active[2]) begin - rd_q <= rd; - end - end - - always @(posedge clk) begin - if (instr_any_mul && !(EXTRA_MUL_FFS ? active[3:0] : active[1:0])) begin - if (instr_rs1_signed) - rs1 <= $signed(pcpi_rs1); - else - rs1 <= $unsigned(pcpi_rs1); - - if (instr_rs2_signed) - rs2 <= $signed(pcpi_rs2); - else - rs2 <= $unsigned(pcpi_rs2); - active[0] <= 1; - end else begin - active[0] <= 0; - end - - active[3:1] <= active; - shift_out <= instr_any_mulh; - - if (!resetn) - active <= 0; - end - - assign pcpi_wr = active[EXTRA_MUL_FFS ? 3 : 1]; - assign pcpi_wait = 0; - assign pcpi_ready = active[EXTRA_MUL_FFS ? 3 : 1]; -`ifdef RISCV_FORMAL_ALTOPS - assign pcpi_rd = - instr_mul ? (pcpi_rs1 + pcpi_rs2) ^ 32'h5876063e : - instr_mulh ? (pcpi_rs1 + pcpi_rs2) ^ 32'hf6583fb7 : - instr_mulhsu ? (pcpi_rs1 - pcpi_rs2) ^ 32'hecfbe137 : - instr_mulhu ? (pcpi_rs1 + pcpi_rs2) ^ 32'h949ce5e8 : 1'bx; -`else - assign pcpi_rd = shift_out ? (EXTRA_MUL_FFS ? rd_q : rd) >> 32 : (EXTRA_MUL_FFS ? rd_q : rd); -`endif -endmodule - - -/*************************************************************** - * picorv32_pcpi_div - ***************************************************************/ - -module picorv32_pcpi_div ( - input clk, resetn, - - input pcpi_valid, - input [31:0] pcpi_insn, - input [31:0] pcpi_rs1, - input [31:0] pcpi_rs2, - output reg pcpi_wr, - output reg [31:0] pcpi_rd, - output reg pcpi_wait, - output reg pcpi_ready -); - reg instr_div, instr_divu, instr_rem, instr_remu; - wire instr_any_div_rem = |{instr_div, instr_divu, instr_rem, instr_remu}; - - reg pcpi_wait_q; - wire start = pcpi_wait && !pcpi_wait_q; - - always @(posedge clk) begin - instr_div <= 0; - instr_divu <= 0; - instr_rem <= 0; - instr_remu <= 0; - - if (resetn && pcpi_valid && !pcpi_ready && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001) begin - case (pcpi_insn[14:12]) - 3'b100: instr_div <= 1; - 3'b101: instr_divu <= 1; - 3'b110: instr_rem <= 1; - 3'b111: instr_remu <= 1; - endcase - end - - pcpi_wait <= instr_any_div_rem && resetn; - pcpi_wait_q <= pcpi_wait && resetn; - end - - reg [31:0] dividend; - reg [62:0] divisor; - reg [31:0] quotient; - reg [31:0] quotient_msk; - reg running; - reg outsign; - - always @(posedge clk) begin - pcpi_ready <= 0; - pcpi_wr <= 0; - pcpi_rd <= 'bx; - - if (!resetn) begin - running <= 0; - end else - if (start) begin - running <= 1; - dividend <= (instr_div || instr_rem) && pcpi_rs1[31] ? -pcpi_rs1 : pcpi_rs1; - divisor <= ((instr_div || instr_rem) && pcpi_rs2[31] ? -pcpi_rs2 : pcpi_rs2) << 31; - outsign <= (instr_div && (pcpi_rs1[31] != pcpi_rs2[31]) && |pcpi_rs2) || (instr_rem && pcpi_rs1[31]); - quotient <= 0; - quotient_msk <= 1 << 31; - end else - if (!quotient_msk && running) begin - running <= 0; - pcpi_ready <= 1; - pcpi_wr <= 1; -`ifdef RISCV_FORMAL_ALTOPS - case (1) - instr_div: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h7f8529ec; - instr_divu: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h10e8fd70; - instr_rem: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h8da68fa5; - instr_remu: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h3138d0e1; - endcase -`else - if (instr_div || instr_divu) - pcpi_rd <= outsign ? -quotient : quotient; - else - pcpi_rd <= outsign ? -dividend : dividend; -`endif - end else begin - if (divisor <= dividend) begin - dividend <= dividend - divisor; - quotient <= quotient | quotient_msk; - end - divisor <= divisor >> 1; -`ifdef RISCV_FORMAL_ALTOPS - quotient_msk <= quotient_msk >> 5; -`else - quotient_msk <= quotient_msk >> 1; -`endif - end - end -endmodule - - -/*************************************************************** - * picorv32_axi - ***************************************************************/ - -module picorv32_axi #( - parameter [ 0:0] ENABLE_COUNTERS = 1, - parameter [ 0:0] ENABLE_COUNTERS64 = 1, - parameter [ 0:0] ENABLE_REGS_16_31 = 1, - parameter [ 0:0] ENABLE_REGS_DUALPORT = 1, - parameter [ 0:0] TWO_STAGE_SHIFT = 1, - parameter [ 0:0] BARREL_SHIFTER = 0, - parameter [ 0:0] TWO_CYCLE_COMPARE = 0, - parameter [ 0:0] TWO_CYCLE_ALU = 0, - parameter [ 0:0] COMPRESSED_ISA = 0, - parameter [ 0:0] CATCH_MISALIGN = 1, - parameter [ 0:0] CATCH_ILLINSN = 1, - parameter [ 0:0] ENABLE_PCPI = 0, - parameter [ 0:0] ENABLE_MUL = 0, - parameter [ 0:0] ENABLE_FAST_MUL = 0, - parameter [ 0:0] ENABLE_DIV = 0, - parameter [ 0:0] ENABLE_IRQ = 0, - parameter [ 0:0] ENABLE_IRQ_QREGS = 1, - parameter [ 0:0] ENABLE_IRQ_TIMER = 1, - parameter [ 0:0] ENABLE_TRACE = 0, - parameter [ 0:0] REGS_INIT_ZERO = 0, - parameter [31:0] MASKED_IRQ = 32'h 0000_0000, - parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff, - parameter [31:0] PROGADDR_RESET = 32'h 0000_0000, - parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010, - parameter [31:0] STACKADDR = 32'h ffff_ffff -) ( - input clk, resetn, - output trap, - - // AXI4-lite master memory interface - - output mem_axi_awvalid, - input mem_axi_awready, - output [31:0] mem_axi_awaddr, - output [ 2:0] mem_axi_awprot, - - output mem_axi_wvalid, - input mem_axi_wready, - output [31:0] mem_axi_wdata, - output [ 3:0] mem_axi_wstrb, - - input mem_axi_bvalid, - output mem_axi_bready, - - output mem_axi_arvalid, - input mem_axi_arready, - output [31:0] mem_axi_araddr, - output [ 2:0] mem_axi_arprot, - - input mem_axi_rvalid, - output mem_axi_rready, - input [31:0] mem_axi_rdata, - - // Pico Co-Processor Interface (PCPI) - output pcpi_valid, - output [31:0] pcpi_insn, - output [31:0] pcpi_rs1, - output [31:0] pcpi_rs2, - input pcpi_wr, - input [31:0] pcpi_rd, - input pcpi_wait, - input pcpi_ready, - - // IRQ interface - input [31:0] irq, - output [31:0] eoi, - -`ifdef RISCV_FORMAL - output rvfi_valid, - output [63:0] rvfi_order, - output [31:0] rvfi_insn, - output rvfi_trap, - output rvfi_halt, - output rvfi_intr, - output [ 4:0] rvfi_rs1_addr, - output [ 4:0] rvfi_rs2_addr, - output [31:0] rvfi_rs1_rdata, - output [31:0] rvfi_rs2_rdata, - output [ 4:0] rvfi_rd_addr, - output [31:0] rvfi_rd_wdata, - output [31:0] rvfi_pc_rdata, - output [31:0] rvfi_pc_wdata, - output [31:0] rvfi_mem_addr, - output [ 3:0] rvfi_mem_rmask, - output [ 3:0] rvfi_mem_wmask, - output [31:0] rvfi_mem_rdata, - output [31:0] rvfi_mem_wdata, -`endif - - // Trace Interface - output trace_valid, - output [35:0] trace_data -); - wire mem_valid; - wire [31:0] mem_addr; - wire [31:0] mem_wdata; - wire [ 3:0] mem_wstrb; - wire mem_instr; - wire mem_ready; - wire [31:0] mem_rdata; - - picorv32_axi_adapter axi_adapter ( - .clk (clk ), - .resetn (resetn ), - .mem_axi_awvalid(mem_axi_awvalid), - .mem_axi_awready(mem_axi_awready), - .mem_axi_awaddr (mem_axi_awaddr ), - .mem_axi_awprot (mem_axi_awprot ), - .mem_axi_wvalid (mem_axi_wvalid ), - .mem_axi_wready (mem_axi_wready ), - .mem_axi_wdata (mem_axi_wdata ), - .mem_axi_wstrb (mem_axi_wstrb ), - .mem_axi_bvalid (mem_axi_bvalid ), - .mem_axi_bready (mem_axi_bready ), - .mem_axi_arvalid(mem_axi_arvalid), - .mem_axi_arready(mem_axi_arready), - .mem_axi_araddr (mem_axi_araddr ), - .mem_axi_arprot (mem_axi_arprot ), - .mem_axi_rvalid (mem_axi_rvalid ), - .mem_axi_rready (mem_axi_rready ), - .mem_axi_rdata (mem_axi_rdata ), - .mem_valid (mem_valid ), - .mem_instr (mem_instr ), - .mem_ready (mem_ready ), - .mem_addr (mem_addr ), - .mem_wdata (mem_wdata ), - .mem_wstrb (mem_wstrb ), - .mem_rdata (mem_rdata ) - ); - - picorv32 #( - .ENABLE_COUNTERS (ENABLE_COUNTERS ), - .ENABLE_COUNTERS64 (ENABLE_COUNTERS64 ), - .ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ), - .ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT), - .TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ), - .BARREL_SHIFTER (BARREL_SHIFTER ), - .TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ), - .TWO_CYCLE_ALU (TWO_CYCLE_ALU ), - .COMPRESSED_ISA (COMPRESSED_ISA ), - .CATCH_MISALIGN (CATCH_MISALIGN ), - .CATCH_ILLINSN (CATCH_ILLINSN ), - .ENABLE_PCPI (ENABLE_PCPI ), - .ENABLE_MUL (ENABLE_MUL ), - .ENABLE_FAST_MUL (ENABLE_FAST_MUL ), - .ENABLE_DIV (ENABLE_DIV ), - .ENABLE_IRQ (ENABLE_IRQ ), - .ENABLE_IRQ_QREGS (ENABLE_IRQ_QREGS ), - .ENABLE_IRQ_TIMER (ENABLE_IRQ_TIMER ), - .ENABLE_TRACE (ENABLE_TRACE ), - .REGS_INIT_ZERO (REGS_INIT_ZERO ), - .MASKED_IRQ (MASKED_IRQ ), - .LATCHED_IRQ (LATCHED_IRQ ), - .PROGADDR_RESET (PROGADDR_RESET ), - .PROGADDR_IRQ (PROGADDR_IRQ ), - .STACKADDR (STACKADDR ) - ) picorv32_core ( - .clk (clk ), - .resetn (resetn), - .trap (trap ), - - .mem_valid(mem_valid), - .mem_addr (mem_addr ), - .mem_wdata(mem_wdata), - .mem_wstrb(mem_wstrb), - .mem_instr(mem_instr), - .mem_ready(mem_ready), - .mem_rdata(mem_rdata), - - .pcpi_valid(pcpi_valid), - .pcpi_insn (pcpi_insn ), - .pcpi_rs1 (pcpi_rs1 ), - .pcpi_rs2 (pcpi_rs2 ), - .pcpi_wr (pcpi_wr ), - .pcpi_rd (pcpi_rd ), - .pcpi_wait (pcpi_wait ), - .pcpi_ready(pcpi_ready), - - .irq(irq), - .eoi(eoi), - -`ifdef RISCV_FORMAL - .rvfi_valid (rvfi_valid ), - .rvfi_order (rvfi_order ), - .rvfi_insn (rvfi_insn ), - .rvfi_trap (rvfi_trap ), - .rvfi_halt (rvfi_halt ), - .rvfi_intr (rvfi_intr ), - .rvfi_rs1_addr (rvfi_rs1_addr ), - .rvfi_rs2_addr (rvfi_rs2_addr ), - .rvfi_rs1_rdata(rvfi_rs1_rdata), - .rvfi_rs2_rdata(rvfi_rs2_rdata), - .rvfi_rd_addr (rvfi_rd_addr ), - .rvfi_rd_wdata (rvfi_rd_wdata ), - .rvfi_pc_rdata (rvfi_pc_rdata ), - .rvfi_pc_wdata (rvfi_pc_wdata ), - .rvfi_mem_addr (rvfi_mem_addr ), - .rvfi_mem_rmask(rvfi_mem_rmask), - .rvfi_mem_wmask(rvfi_mem_wmask), - .rvfi_mem_rdata(rvfi_mem_rdata), - .rvfi_mem_wdata(rvfi_mem_wdata), -`endif - - .trace_valid(trace_valid), - .trace_data (trace_data) - ); -endmodule - - -/*************************************************************** - * picorv32_axi_adapter - ***************************************************************/ - -module picorv32_axi_adapter ( - input clk, resetn, - - // AXI4-lite master memory interface - - output mem_axi_awvalid, - input mem_axi_awready, - output [31:0] mem_axi_awaddr, - output [ 2:0] mem_axi_awprot, - - output mem_axi_wvalid, - input mem_axi_wready, - output [31:0] mem_axi_wdata, - output [ 3:0] mem_axi_wstrb, - - input mem_axi_bvalid, - output mem_axi_bready, - - output mem_axi_arvalid, - input mem_axi_arready, - output [31:0] mem_axi_araddr, - output [ 2:0] mem_axi_arprot, - - input mem_axi_rvalid, - output mem_axi_rready, - input [31:0] mem_axi_rdata, - - // Native PicoRV32 memory interface - - input mem_valid, - input mem_instr, - output mem_ready, - input [31:0] mem_addr, - input [31:0] mem_wdata, - input [ 3:0] mem_wstrb, - output [31:0] mem_rdata -); - reg ack_awvalid; - reg ack_arvalid; - reg ack_wvalid; - reg xfer_done; - - assign mem_axi_awvalid = mem_valid && |mem_wstrb && !ack_awvalid; - assign mem_axi_awaddr = mem_addr; - assign mem_axi_awprot = 0; - - assign mem_axi_arvalid = mem_valid && !mem_wstrb && !ack_arvalid; - assign mem_axi_araddr = mem_addr; - assign mem_axi_arprot = mem_instr ? 3'b100 : 3'b000; - - assign mem_axi_wvalid = mem_valid && |mem_wstrb && !ack_wvalid; - assign mem_axi_wdata = mem_wdata; - assign mem_axi_wstrb = mem_wstrb; - - assign mem_ready = mem_axi_bvalid || mem_axi_rvalid; - assign mem_axi_bready = mem_valid && |mem_wstrb; - assign mem_axi_rready = mem_valid && !mem_wstrb; - assign mem_rdata = mem_axi_rdata; - - always @(posedge clk) begin - if (!resetn) begin - ack_awvalid <= 0; - end else begin - xfer_done <= mem_valid && mem_ready; - if (mem_axi_awready && mem_axi_awvalid) - ack_awvalid <= 1; - if (mem_axi_arready && mem_axi_arvalid) - ack_arvalid <= 1; - if (mem_axi_wready && mem_axi_wvalid) - ack_wvalid <= 1; - if (xfer_done || !mem_valid) begin - ack_awvalid <= 0; - ack_arvalid <= 0; - ack_wvalid <= 0; - end - end - end -endmodule - - -/*************************************************************** - * picorv32_wb - ***************************************************************/ - -module picorv32_wb #( - parameter [ 0:0] ENABLE_COUNTERS = 1, - parameter [ 0:0] ENABLE_COUNTERS64 = 1, - parameter [ 0:0] ENABLE_REGS_16_31 = 1, - parameter [ 0:0] ENABLE_REGS_DUALPORT = 1, - parameter [ 0:0] TWO_STAGE_SHIFT = 1, - parameter [ 0:0] BARREL_SHIFTER = 0, - parameter [ 0:0] TWO_CYCLE_COMPARE = 0, - parameter [ 0:0] TWO_CYCLE_ALU = 0, - parameter [ 0:0] COMPRESSED_ISA = 0, - parameter [ 0:0] CATCH_MISALIGN = 1, - parameter [ 0:0] CATCH_ILLINSN = 1, - parameter [ 0:0] ENABLE_PCPI = 0, - parameter [ 0:0] ENABLE_MUL = 0, - parameter [ 0:0] ENABLE_FAST_MUL = 0, - parameter [ 0:0] ENABLE_DIV = 0, - parameter [ 0:0] ENABLE_IRQ = 0, - parameter [ 0:0] ENABLE_IRQ_QREGS = 1, - parameter [ 0:0] ENABLE_IRQ_TIMER = 1, - parameter [ 0:0] ENABLE_TRACE = 0, - parameter [ 0:0] REGS_INIT_ZERO = 0, - parameter [31:0] MASKED_IRQ = 32'h 0000_0000, - parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff, - parameter [31:0] PROGADDR_RESET = 32'h 0000_0000, - parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010, - parameter [31:0] STACKADDR = 32'h ffff_ffff -) ( - output trap, - - // Wishbone interfaces - input wb_rst_i, - input wb_clk_i, - - output reg [31:0] wbm_adr_o, - output reg [31:0] wbm_dat_o, - input [31:0] wbm_dat_i, - output reg wbm_we_o, - output reg [3:0] wbm_sel_o, - output reg wbm_stb_o, - input wbm_ack_i, - output reg wbm_cyc_o, - - // Pico Co-Processor Interface (PCPI) - output pcpi_valid, - output [31:0] pcpi_insn, - output [31:0] pcpi_rs1, - output [31:0] pcpi_rs2, - input pcpi_wr, - input [31:0] pcpi_rd, - input pcpi_wait, - input pcpi_ready, - - // IRQ interface - input [31:0] irq, - output [31:0] eoi, - -`ifdef RISCV_FORMAL - output rvfi_valid, - output [63:0] rvfi_order, - output [31:0] rvfi_insn, - output rvfi_trap, - output rvfi_halt, - output rvfi_intr, - output [ 4:0] rvfi_rs1_addr, - output [ 4:0] rvfi_rs2_addr, - output [31:0] rvfi_rs1_rdata, - output [31:0] rvfi_rs2_rdata, - output [ 4:0] rvfi_rd_addr, - output [31:0] rvfi_rd_wdata, - output [31:0] rvfi_pc_rdata, - output [31:0] rvfi_pc_wdata, - output [31:0] rvfi_mem_addr, - output [ 3:0] rvfi_mem_rmask, - output [ 3:0] rvfi_mem_wmask, - output [31:0] rvfi_mem_rdata, - output [31:0] rvfi_mem_wdata, -`endif - - // Trace Interface - output trace_valid, - output [35:0] trace_data, - - output mem_instr -); - wire mem_valid; - wire [31:0] mem_addr; - wire [31:0] mem_wdata; - wire [ 3:0] mem_wstrb; - reg mem_ready; - reg [31:0] mem_rdata; - - wire clk; - wire resetn; - - assign clk = wb_clk_i; - assign resetn = ~wb_rst_i; - - picorv32 #( - .ENABLE_COUNTERS (ENABLE_COUNTERS ), - .ENABLE_COUNTERS64 (ENABLE_COUNTERS64 ), - .ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ), - .ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT), - .TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ), - .BARREL_SHIFTER (BARREL_SHIFTER ), - .TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ), - .TWO_CYCLE_ALU (TWO_CYCLE_ALU ), - .COMPRESSED_ISA (COMPRESSED_ISA ), - .CATCH_MISALIGN (CATCH_MISALIGN ), - .CATCH_ILLINSN (CATCH_ILLINSN ), - .ENABLE_PCPI (ENABLE_PCPI ), - .ENABLE_MUL (ENABLE_MUL ), - .ENABLE_FAST_MUL (ENABLE_FAST_MUL ), - .ENABLE_DIV (ENABLE_DIV ), - .ENABLE_IRQ (ENABLE_IRQ ), - .ENABLE_IRQ_QREGS (ENABLE_IRQ_QREGS ), - .ENABLE_IRQ_TIMER (ENABLE_IRQ_TIMER ), - .ENABLE_TRACE (ENABLE_TRACE ), - .REGS_INIT_ZERO (REGS_INIT_ZERO ), - .MASKED_IRQ (MASKED_IRQ ), - .LATCHED_IRQ (LATCHED_IRQ ), - .PROGADDR_RESET (PROGADDR_RESET ), - .PROGADDR_IRQ (PROGADDR_IRQ ), - .STACKADDR (STACKADDR ) - ) picorv32_core ( - .clk (clk ), - .resetn (resetn), - .trap (trap ), - - .mem_valid(mem_valid), - .mem_addr (mem_addr ), - .mem_wdata(mem_wdata), - .mem_wstrb(mem_wstrb), - .mem_instr(mem_instr), - .mem_ready(mem_ready), - .mem_rdata(mem_rdata), - - .pcpi_valid(pcpi_valid), - .pcpi_insn (pcpi_insn ), - .pcpi_rs1 (pcpi_rs1 ), - .pcpi_rs2 (pcpi_rs2 ), - .pcpi_wr (pcpi_wr ), - .pcpi_rd (pcpi_rd ), - .pcpi_wait (pcpi_wait ), - .pcpi_ready(pcpi_ready), - - .irq(irq), - .eoi(eoi), - -`ifdef RISCV_FORMAL - .rvfi_valid (rvfi_valid ), - .rvfi_order (rvfi_order ), - .rvfi_insn (rvfi_insn ), - .rvfi_trap (rvfi_trap ), - .rvfi_halt (rvfi_halt ), - .rvfi_intr (rvfi_intr ), - .rvfi_rs1_addr (rvfi_rs1_addr ), - .rvfi_rs2_addr (rvfi_rs2_addr ), - .rvfi_rs1_rdata(rvfi_rs1_rdata), - .rvfi_rs2_rdata(rvfi_rs2_rdata), - .rvfi_rd_addr (rvfi_rd_addr ), - .rvfi_rd_wdata (rvfi_rd_wdata ), - .rvfi_pc_rdata (rvfi_pc_rdata ), - .rvfi_pc_wdata (rvfi_pc_wdata ), - .rvfi_mem_addr (rvfi_mem_addr ), - .rvfi_mem_rmask(rvfi_mem_rmask), - .rvfi_mem_wmask(rvfi_mem_wmask), - .rvfi_mem_rdata(rvfi_mem_rdata), - .rvfi_mem_wdata(rvfi_mem_wdata), -`endif - - .trace_valid(trace_valid), - .trace_data (trace_data) - ); - // Wishbone Controller - localparam IDLE = 2'b00; - localparam WBSTART = 2'b01; - localparam WBEND = 2'b10; - - reg [1:0] state; - - wire we; - assign we = (mem_wstrb[0] | mem_wstrb[1] | mem_wstrb[2] | mem_wstrb[3]); - - always @(posedge wb_clk_i) begin - if (wb_rst_i) begin - wbm_adr_o <= 0; - wbm_dat_o <= 0; - wbm_we_o <= 0; - wbm_sel_o <= 0; - wbm_stb_o <= 0; - wbm_cyc_o <= 0; - state <= IDLE; - end else begin - case (state) - IDLE: begin - if (mem_valid) begin - wbm_adr_o <= mem_addr; - wbm_dat_o <= mem_wdata; - wbm_we_o <= we; - wbm_sel_o <= mem_wstrb; - - wbm_stb_o <= 1'b1; - wbm_cyc_o <= 1'b1; - state <= WBSTART; - end else begin - mem_ready <= 1'b0; - - wbm_stb_o <= 1'b0; - wbm_cyc_o <= 1'b0; - wbm_we_o <= 1'b0; - end - end - WBSTART:begin - if (wbm_ack_i) begin - mem_rdata <= wbm_dat_i; - mem_ready <= 1'b1; - - state <= WBEND; - - wbm_stb_o <= 1'b0; - wbm_cyc_o <= 1'b0; - wbm_we_o <= 1'b0; - end - end - WBEND: begin - mem_ready <= 1'b0; - - state <= IDLE; - end - default: - state <= IDLE; - endcase - end - end -endmodule -`default_nettype wire
diff --git a/caravel/rtl/ring_osc2x13.v b/caravel/rtl/ring_osc2x13.v deleted file mode 100644 index f20110e..0000000 --- a/caravel/rtl/ring_osc2x13.v +++ /dev/null
@@ -1,250 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -// Tunable ring oscillator---synthesizable (physical) version. -// -// NOTE: This netlist cannot be simulated correctly due to lack -// of accurate timing in the digital cell verilog models. - -module delay_stage(in, trim, out); - input in; - input [1:0] trim; - output out; - - wire d0, d1, d2, ts; - - sky130_fd_sc_hd__clkbuf_2 delaybuf0 ( - .A(in), - .X(ts) - ); - - sky130_fd_sc_hd__clkbuf_1 delaybuf1 ( - .A(ts), - .X(d0) - ); - - sky130_fd_sc_hd__einvp_2 delayen1 ( - .A(d0), - .TE(trim[1]), - .Z(d1) - ); - - sky130_fd_sc_hd__einvn_4 delayenb1 ( - .A(ts), - .TE_B(trim[1]), - .Z(d1) - ); - - sky130_fd_sc_hd__clkinv_1 delayint0 ( - .A(d1), - .Y(d2) - ); - - sky130_fd_sc_hd__einvp_2 delayen0 ( - .A(d2), - .TE(trim[0]), - .Z(out) - ); - - sky130_fd_sc_hd__einvn_8 delayenb0 ( - .A(ts), - .TE_B(trim[0]), - .Z(out) - ); - -endmodule - -module start_stage(in, trim, reset, out); - input in; - input [1:0] trim; - input reset; - output out; - - wire d0, d1, d2, ctrl0, one; - - sky130_fd_sc_hd__clkbuf_1 delaybuf0 ( - .A(in), - .X(d0) - ); - - sky130_fd_sc_hd__einvp_2 delayen1 ( - .A(d0), - .TE(trim[1]), - .Z(d1) - ); - - sky130_fd_sc_hd__einvn_4 delayenb1 ( - .A(in), - .TE_B(trim[1]), - .Z(d1) - ); - - sky130_fd_sc_hd__clkinv_1 delayint0 ( - .A(d1), - .Y(d2) - ); - - sky130_fd_sc_hd__einvp_2 delayen0 ( - .A(d2), - .TE(trim[0]), - .Z(out) - ); - - sky130_fd_sc_hd__einvn_8 delayenb0 ( - .A(in), - .TE_B(ctrl0), - .Z(out) - ); - - sky130_fd_sc_hd__einvp_1 reseten0 ( - .A(one), - .TE(reset), - .Z(out) - ); - - sky130_fd_sc_hd__or2_2 ctrlen0 ( - .A(reset), - .B(trim[0]), - .X(ctrl0) - ); - - sky130_fd_sc_hd__conb_1 const1 ( - .HI(one), - .LO() - ); - -endmodule - -// Ring oscillator with 13 stages, each with two trim bits delay -// (see above). Trim is not binary: For trim[1:0], lower bit -// trim[0] is primary trim and must be applied first; upper -// bit trim[1] is secondary trim and should only be applied -// after the primary trim is applied, or it has no effect. -// -// Total effective number of inverter stages in this oscillator -// ranges from 13 at trim 0 to 65 at trim 24. The intention is -// to cover a range greater than 2x so that the midrange can be -// reached over all PVT conditions. -// -// Frequency of this ring oscillator under SPICE simulations at -// nominal PVT is maximum 214 MHz (trim 0), minimum 90 MHz (trim 24). - -module ring_osc2x13(reset, trim, clockp); - input reset; - input [25:0] trim; - output[1:0] clockp; - -`ifdef FUNCTIONAL // i.e., behavioral model below - - reg [1:0] clockp; - reg hiclock; - integer i; - real delay; - wire [5:0] bcount; - - assign bcount = trim[0] + trim[1] + trim[2] - + trim[3] + trim[4] + trim[5] + trim[6] + trim[7] - + trim[8] + trim[9] + trim[10] + trim[11] + trim[12] - + trim[13] + trim[14] + trim[15] + trim[16] + trim[17] - + trim[18] + trim[19] + trim[20] + trim[21] + trim[22] - + trim[23] + trim[24] + trim[25]; - - initial begin - hiclock <= 1'b0; - delay = 3.0; - end - - // Fastest operation is 214 MHz = 4.67ns - // Delay per trim is 0.02385 - // Run "hiclock" at 2x this rate, then use positive and negative - // edges to derive the 0 and 90 degree phase clocks. - - always #delay begin - hiclock <= (hiclock === 1'b0); - end - - always @(trim) begin - // Implement trim as a variable delay, one delay per trim bit - delay = 1.168 + 0.012 * $itor(bcount); - end - - always @(posedge hiclock or posedge reset) begin - if (reset == 1'b1) begin - clockp[0] <= 1'b0; - end else begin - clockp[0] <= (clockp[0] === 1'b0); - end - end - - always @(negedge hiclock or posedge reset) begin - if (reset == 1'b1) begin - clockp[1] <= 1'b0; - end else begin - clockp[1] <= (clockp[1] === 1'b0); - end - end - -`else // !FUNCTIONAL; i.e., gate level netlist below - - wire [1:0] clockp; - wire [12:0] d; - wire [1:0] c; - - // Main oscillator loop stages - - genvar i; - generate - for (i = 0; i < 12; i = i + 1) begin : dstage - delay_stage id ( - .in(d[i]), - .trim({trim[i+13], trim[i]}), - .out(d[i+1]) - ); - end - endgenerate - - // Reset/startup stage - - start_stage iss ( - .in(d[12]), - .trim({trim[25], trim[12]}), - .reset(reset), - .out(d[0]) - ); - - // Buffered outputs a 0 and 90 degrees phase (approximately) - - sky130_fd_sc_hd__clkinv_2 ibufp00 ( - .A(d[0]), - .Y(c[0]) - ); - sky130_fd_sc_hd__clkinv_8 ibufp01 ( - .A(c[0]), - .Y(clockp[0]) - ); - sky130_fd_sc_hd__clkinv_2 ibufp10 ( - .A(d[6]), - .Y(c[1]) - ); - sky130_fd_sc_hd__clkinv_8 ibufp11 ( - .A(c[1]), - .Y(clockp[1]) - ); - -`endif // !FUNCTIONAL - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/simple_por.v b/caravel/rtl/simple_por.v deleted file mode 100644 index 8168c0b..0000000 --- a/caravel/rtl/simple_por.v +++ /dev/null
@@ -1,92 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -`timescale 1 ns / 1 ps - -module simple_por( -`ifdef USE_POWER_PINS - inout vdd3v3, - inout vdd1v8, - inout vss, -`endif - output porb_h, - output porb_l, - output por_l -); - - wire mid, porb_h; - reg inode; - - // This is a behavioral model! Actual circuit is a resitor dumping - // current (slowly) from vdd3v3 onto a capacitor, and this fed into - // two schmitt triggers for strong hysteresis/glitch tolerance. - - initial begin - inode <= 1'b0; - end - - // Emulate current source on capacitor as a 500ns delay either up or - // down. Note that this is sped way up for verilog simulation; the - // actual circuit is set to a 15ms delay. - - always @(posedge vdd3v3) begin - #500 inode <= 1'b1; - end - always @(negedge vdd3v3) begin - #500 inode <= 1'b0; - end - - // Instantiate two shmitt trigger buffers in series - - sky130_fd_sc_hvl__schmittbuf_1 hystbuf1 ( -`ifdef USE_POWER_PINS - .VPWR(vdd3v3), - .VGND(vss), - .VPB(vdd3v3), - .VNB(vss), -`endif - .A(inode), - .X(mid) - ); - - sky130_fd_sc_hvl__schmittbuf_1 hystbuf2 ( -`ifdef USE_POWER_PINS - .VPWR(vdd3v3), - .VGND(vss), - .VPB(vdd3v3), - .VNB(vss), -`endif - .A(mid), - .X(porb_h) - ); - - sky130_fd_sc_hvl__lsbufhv2lv_1 porb_level ( -`ifdef USE_POWER_PINS - .VPWR(vdd3v3), - .VPB(vdd3v3), - .LVPWR(vdd1v8), - .VNB(vss), - .VGND(vss), -`endif - .A(porb_h), - .X(porb_l) - ); - - // since this is behavioral anyway, but this should be - // replaced by a proper inverter - assign por_l = ~porb_l; -endmodule -`default_nettype wire
diff --git a/caravel/rtl/simple_spi_master.v b/caravel/rtl/simple_spi_master.v deleted file mode 100644 index 60a923b..0000000 --- a/caravel/rtl/simple_spi_master.v +++ /dev/null
@@ -1,410 +0,0 @@ -`default_nettype none -// SPDX-FileCopyrightText: 2019 Efabless Corporation -// -// 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 -//---------------------------------------------------------------------------- -// Module: simple_spi_master -// -//---------------------------------------------------------------------------- -// Copyright (C) 2019 efabless, inc. -// -// 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. -// -//-------------------------------------------------------------------- -// -// resetn: active low async reset -// clk: master clock (before prescaler) -// stream: -// 0 = apply/release CSB separately for each byte -// 1 = apply CSB until stream bit is cleared -// mlb: -// 0 = msb 1st -// 1 = lsb 1st -// invsck: -// 0 = normal SCK -// 1 = inverted SCK -// invcsb: -// 0 = normal CSB (active low) -// 1 = inverted CSB (active high) -// mode: -// 0 = read and change data on opposite SCK edges -// 1 = read and change data on the same SCK edge -// enable: -// 0 = disable the SPI master -// 1 = enable the SPI master -// irqena: -// 0 = disable interrupt -// 1 = enable interrupt -// hkconn: -// 0 = housekeeping SPI disconnected -// 1 = housekeeping SPI connected (when SPI master enabled) -// prescaler: count (in master clock cycles) of 1/2 SCK cycle. -// -// reg_dat_we: -// 1 = data write enable -// reg_dat_re: -// 1 = data read enable -// reg_cfg_*: Signaling for read/write of configuration register -// reg_dat_*: Signaling for read/write of data register -// -// err_out: Indicates attempt to read/write before data ready -// (failure to wait for reg_dat_wait to clear) -// -// Between "mode" and "invsck", all four standard SPI modes are supported -// -//-------------------------------------------------------------------- - -module simple_spi_master_wb #( - parameter BASE_ADR = 32'h2100_0000, - parameter CONFIG = 8'h00, - parameter DATA = 8'h04 -) ( - input wb_clk_i, - input wb_rst_i, - input [31:0] wb_adr_i, - input [31:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input wb_cyc_i, - input wb_stb_i, - output wb_ack_o, - output [31:0] wb_dat_o, - - output hk_connect, // Connect to housekeeping SPI - output spi_enabled, // Use to mux pins with GPIO control - input sdi, // SPI input - output csb, // SPI chip select - output sck, // SPI clock - output sdo, // SPI output - output sdoenb, // SPI output enable - output irq // interrupt output -); - - wire [31:0] simple_spi_master_reg_cfg_do; - wire [31:0] simple_spi_master_reg_dat_do; - - wire resetn = ~wb_rst_i; - wire valid = wb_stb_i && wb_cyc_i; - wire simple_spi_master_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG)); - wire simple_spi_master_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA)); - - wire [1:0] reg_cfg_we = (simple_spi_master_reg_cfg_sel) ? - (wb_sel_i[1:0] & {2{wb_we_i}}): 2'b00; - wire reg_dat_we = (simple_spi_master_reg_dat_sel) ? (wb_sel_i[0] & wb_we_i): 1'b0; - wire reg_dat_wait; - - wire [31:0] mem_wdata = wb_dat_i; - wire reg_dat_re = simple_spi_master_reg_dat_sel && !wb_sel_i && ~wb_we_i; - - assign wb_dat_o = (simple_spi_master_reg_cfg_sel) ? simple_spi_master_reg_cfg_do : - simple_spi_master_reg_dat_do; - assign wb_ack_o = (simple_spi_master_reg_cfg_sel || simple_spi_master_reg_dat_sel) - && (!reg_dat_wait); - - simple_spi_master spi_master ( - .resetn(resetn), - .clk(wb_clk_i), - .reg_cfg_we(reg_cfg_we), - .reg_cfg_di(mem_wdata), - .reg_cfg_do(simple_spi_master_reg_cfg_do), - .reg_dat_we(reg_dat_we), - .reg_dat_re(reg_dat_re), - .reg_dat_di(mem_wdata), - .reg_dat_do(simple_spi_master_reg_dat_do), - .reg_dat_wait(reg_dat_wait), - - .hk_connect(hk_connect), // Attach to housekeeping SPI slave - .spi_enabled(spi_enabled), // Mux pins with GPIO - .sdi(sdi), // SPI input - .csb(csb), // SPI chip select - .sck(sck), // SPI clock - .sdo(sdo), // SPI output - .irq_out(irq) // interrupt - ); -endmodule - -module simple_spi_master ( - input resetn, - input clk, // master clock (assume 100MHz) - - input [1:0] reg_cfg_we, - input [31:0] reg_cfg_di, - output [31:0] reg_cfg_do, - - input reg_dat_we, - input reg_dat_re, - input [31:0] reg_dat_di, - output [31:0] reg_dat_do, - output reg_dat_wait, - output irq_out, - output err_out, - - output hk_connect, // Connect to housekeeping SPI - output spi_enabled, // Used to mux pins with GPIO - input sdi, // SPI input - output csb, // SPI chip select - output sck, // SPI clock - output sdo // SPI output -); - - parameter IDLE = 2'b00; - parameter SENDL = 2'b01; - parameter SENDH = 2'b10; - parameter FINISH = 2'b11; - - reg done; - reg isdo, hsck, icsb; - reg [1:0] state; - reg isck; - reg err_out; - - reg [7:0] treg, rreg, d_latched; - reg [2:0] nbit; - - reg [7:0] prescaler; - reg [7:0] count; - reg invsck; - reg invcsb; - reg mlb; - reg irqena; - reg stream; - reg mode; - reg enable; - reg hkconn; - - wire csb; - wire irq_out; - wire sck; - wire sdo; - wire sdoenb; - wire hk_connect; - wire spi_enabled; - - // Define behavior for inverted SCK and inverted CSB - assign csb = (invcsb) ? ~icsb : icsb; - assign sck = (invsck) ? ~isck : isck; - - // No bidirectional 3-pin mode defined, so SDO is enabled whenever CSB is low. - assign sdoenb = icsb; - assign sdo = isdo; - - assign irq_out = irqena & done; - assign hk_connect = (enable == 1'b1) ? hkconn : 1'b0; - assign spi_enabled = enable; - - // Read configuration and data registers - assign reg_cfg_do = {16'd0, hkconn, irqena, enable, stream, mode, - invsck, invcsb, mlb, prescaler}; - assign reg_dat_wait = ~done; - assign reg_dat_do = done ? rreg : ~0; - - // Write configuration register - always @(posedge clk or negedge resetn) begin - if (resetn == 1'b0) begin - prescaler <= 8'd2; - invcsb <= 1'b0; - invsck <= 1'b0; - mlb <= 1'b0; - enable <= 1'b0; - irqena <= 1'b0; - stream <= 1'b0; - mode <= 1'b0; - hkconn <= 1'b0; - end else begin - if (reg_cfg_we[0]) prescaler <= reg_cfg_di[7:0]; - if (reg_cfg_we[1]) begin - mlb <= reg_cfg_di[8]; - invcsb <= reg_cfg_di[9]; - invsck <= reg_cfg_di[10]; - mode <= reg_cfg_di[11]; - stream <= reg_cfg_di[12]; - enable <= reg_cfg_di[13]; - irqena <= reg_cfg_di[14]; - hkconn <= reg_cfg_di[15]; - end //reg_cfg_we[1] - end //resetn - end //always - - // Watch for read and write enables on clk, not hsck, so as not to - // miss them. - - reg w_latched, r_latched; - - always @(posedge clk or negedge resetn) begin - if (resetn == 1'b0) begin - err_out <= 1'b0; - w_latched <= 1'b0; - r_latched <= 1'b0; - d_latched <= 8'd0; - end else begin - // Clear latches on SEND, otherwise latch when seen - if (state == SENDL || state == SENDH) begin - if (reg_dat_we == 1'b0) begin - w_latched <= 1'b0; - end - end else begin - if (reg_dat_we == 1'b1) begin - if (done == 1'b0 && w_latched == 1'b1) begin - err_out <= 1'b1; - end else begin - w_latched <= 1'b1; - d_latched <= reg_dat_di[7:0]; - err_out <= 1'b0; - end - end - end - - if (reg_dat_re == 1'b1) begin - if (r_latched == 1'b1) begin - r_latched <= 1'b0; - end else begin - err_out <= 1'b1; // byte not available - end - end else if (state == FINISH) begin - r_latched <= 1'b1; - end if (state == SENDL || state == SENDH) begin - if (r_latched == 1'b1) begin - err_out <= 1'b1; // last byte was never read - end else begin - r_latched <= 1'b0; - end - end - end - end - - // State transition. - - always @(posedge hsck or negedge resetn) begin - if (resetn == 1'b0) begin - state <= IDLE; - nbit <= 3'd0; - icsb <= 1'b1; - done <= 1'b1; - end else begin - if (state == IDLE) begin - if (w_latched == 1'b1) begin - state <= SENDL; - nbit <= 3'd0; - icsb <= 1'b0; - done <= 1'b0; - end else begin - icsb <= ~stream; - end - end else if (state == SENDL) begin - state <= SENDH; - end else if (state == SENDH) begin - nbit <= nbit + 1; - if (nbit == 3'd7) begin - state <= FINISH; - end else begin - state <= SENDL; - end - end else if (state == FINISH) begin - icsb <= ~stream; - done <= 1'b1; - state <= IDLE; - end - end - end - - // Set up internal clock. The enable bit gates the internal clock - // to shut down the master SPI when disabled. - - always @(posedge clk or negedge resetn) begin - if (resetn == 1'b0) begin - count <= 8'd0; - hsck <= 1'b0; - end else begin - if (enable == 1'b0) begin - count <= 8'd0; - end else begin - count <= count + 1; - if (count == prescaler) begin - hsck <= ~hsck; - count <= 8'd0; - end // count - end // enable - end // resetn - end // always - - // sck is half the rate of hsck - - always @(posedge hsck or negedge resetn) begin - if (resetn == 1'b0) begin - isck <= 1'b0; - end else begin - if (state == IDLE || state == FINISH) - isck <= 1'b0; - else - isck <= ~isck; - end // resetn - end // always - - // Main procedure: read, write, shift data - - always @(posedge hsck or negedge resetn) begin - if (resetn == 1'b0) begin - rreg <= 8'hff; - treg <= 8'hff; - isdo <= 1'b0; - end else begin - if (isck == 1'b0 && (state == SENDL || state == SENDH)) begin - if (mlb == 1'b1) begin - // LSB first, sdi@msb -> right shift - rreg <= {sdi, rreg[7:1]}; - end else begin - // MSB first, sdi@lsb -> left shift - rreg <= {rreg[6:0], sdi}; - end - end // read on ~isck - - if (w_latched == 1'b1) begin - if (mlb == 1'b1) begin - treg <= {1'b1, d_latched[7:1]}; - isdo <= d_latched[0]; - end else begin - treg <= {d_latched[6:0], 1'b1}; - isdo <= d_latched[7]; - end // mlb - end else if ((mode ^ isck) == 1'b1) begin - if (mlb == 1'b1) begin - // LSB first, shift right - treg <= {1'b1, treg[7:1]}; - isdo <= treg[0]; - end else begin - // MSB first shift LEFT - treg <= {treg[6:0], 1'b1}; - isdo <= treg[7]; - end // mlb - end // write on mode ^ isck - end // resetn - end // always - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/simpleuart.v b/caravel/rtl/simpleuart.v deleted file mode 100644 index 12be167..0000000 --- a/caravel/rtl/simpleuart.v +++ /dev/null
@@ -1,223 +0,0 @@ -`default_nettype none -/* - * SPDX-FileCopyrightText: 2015 Clifford Wolf - * PicoSoC - A simple example SoC using PicoRV32 - * - * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * SPDX-License-Identifier: ISC - */ - -module simpleuart_wb # ( - parameter BASE_ADR = 32'h 2000_0000, - parameter CLK_DIV = 8'h00, - parameter DATA = 8'h04, - parameter CONFIG = 8'h08 -) ( - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_adr_i, // (verify): input address was originaly 22 bits , why ? (max number of words ?) - input [31:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input wb_cyc_i, - input wb_stb_i, - - output wb_ack_o, - output [31:0] wb_dat_o, - - output uart_enabled, - output ser_tx, - input ser_rx - -); - wire [31:0] simpleuart_reg_div_do; - wire [31:0] simpleuart_reg_dat_do; - wire [31:0] simpleuart_reg_cfg_do; - wire reg_dat_wait; - - wire resetn = ~wb_rst_i; - wire valid = wb_stb_i && wb_cyc_i; - wire simpleuart_reg_div_sel = valid && (wb_adr_i == (BASE_ADR | CLK_DIV)); - wire simpleuart_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA)); - wire simpleuart_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG)); - - wire [3:0] reg_div_we = simpleuart_reg_div_sel ? (wb_sel_i & {4{wb_we_i}}): 4'b 0000; - wire reg_dat_we = simpleuart_reg_dat_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0; // simpleuart_reg_dat_sel ? mem_wstrb[0] : 1'b 0 - wire reg_cfg_we = simpleuart_reg_cfg_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0; - - wire [31:0] mem_wdata = wb_dat_i; - wire reg_dat_re = simpleuart_reg_dat_sel && !wb_sel_i && ~wb_we_i; // read_enable - - assign wb_dat_o = simpleuart_reg_div_sel ? simpleuart_reg_div_do: - simpleuart_reg_cfg_sel ? simpleuart_reg_cfg_do: - simpleuart_reg_dat_do; - assign wb_ack_o = (simpleuart_reg_div_sel || simpleuart_reg_dat_sel - || simpleuart_reg_cfg_sel) && (!reg_dat_wait); - - simpleuart simpleuart ( - .clk (wb_clk_i), - .resetn (resetn), - - .ser_tx (ser_tx), - .ser_rx (ser_rx), - .enabled (uart_enabled), - - .reg_div_we (reg_div_we), - .reg_div_di (mem_wdata), - .reg_div_do (simpleuart_reg_div_do), - - .reg_cfg_we (reg_cfg_we), - .reg_cfg_di (mem_wdata), - .reg_cfg_do (simpleuart_reg_cfg_do), - - .reg_dat_we (reg_dat_we), - .reg_dat_re (reg_dat_re), - .reg_dat_di (mem_wdata), - .reg_dat_do (simpleuart_reg_dat_do), - .reg_dat_wait(reg_dat_wait) - ); - -endmodule - -module simpleuart ( - input clk, - input resetn, - - output enabled, - output ser_tx, - input ser_rx, - - input [3:0] reg_div_we, - input [31:0] reg_div_di, - output [31:0] reg_div_do, - - input reg_cfg_we, - input [31:0] reg_cfg_di, - output [31:0] reg_cfg_do, - - input reg_dat_we, - input reg_dat_re, - input [31:0] reg_dat_di, - output [31:0] reg_dat_do, - output reg_dat_wait -); - reg [31:0] cfg_divider; - reg enabled; - - reg [3:0] recv_state; - reg [31:0] recv_divcnt; - reg [7:0] recv_pattern; - reg [7:0] recv_buf_data; - reg recv_buf_valid; - - reg [9:0] send_pattern; - reg [3:0] send_bitcnt; - reg [31:0] send_divcnt; - reg send_dummy; - - assign reg_div_do = cfg_divider; - assign reg_cfg_do = {31'd0, enabled}; - - assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy); - assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0; - - always @(posedge clk) begin - if (!resetn) begin - cfg_divider <= 1; - enabled <= 1'b0; - end else begin - if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0]; - if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8]; - if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16]; - if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24]; - if (reg_cfg_we) enabled <= reg_div_di[0]; - end - end - - always @(posedge clk) begin - if (!resetn) begin - recv_state <= 0; - recv_divcnt <= 0; - recv_pattern <= 0; - recv_buf_data <= 0; - recv_buf_valid <= 0; - end else begin - recv_divcnt <= recv_divcnt + 1; - if (reg_dat_re) - recv_buf_valid <= 0; - case (recv_state) - 0: begin - if (!ser_rx && enabled) - recv_state <= 1; - recv_divcnt <= 0; - end - 1: begin - if (2*recv_divcnt > cfg_divider) begin - recv_state <= 2; - recv_divcnt <= 0; - end - end - 10: begin - if (recv_divcnt > cfg_divider) begin - recv_buf_data <= recv_pattern; - recv_buf_valid <= 1; - recv_state <= 0; - end - end - default: begin - if (recv_divcnt > cfg_divider) begin - recv_pattern <= {ser_rx, recv_pattern[7:1]}; - recv_state <= recv_state + 1; - recv_divcnt <= 0; - end - end - endcase - end - end - - assign ser_tx = send_pattern[0]; - - always @(posedge clk) begin - if (reg_div_we && enabled) - send_dummy <= 1; - send_divcnt <= send_divcnt + 1; - if (!resetn) begin - send_pattern <= ~0; - send_bitcnt <= 0; - send_divcnt <= 0; - send_dummy <= 1; - end else begin - if (send_dummy && !send_bitcnt) begin - send_pattern <= ~0; - send_bitcnt <= 15; - send_divcnt <= 0; - send_dummy <= 0; - end else - if (reg_dat_we && !send_bitcnt) begin - send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0}; - send_bitcnt <= 10; - send_divcnt <= 0; - end else - if (send_divcnt > cfg_divider && send_bitcnt) begin - send_pattern <= {1'b1, send_pattern[9:1]}; - send_bitcnt <= send_bitcnt - 1; - send_divcnt <= 0; - end - end - end -endmodule -`default_nettype wire
diff --git a/caravel/rtl/sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped.v b/caravel/rtl/sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped.v deleted file mode 100644 index 19f19b0..0000000 --- a/caravel/rtl/sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped.v +++ /dev/null
@@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -module sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped ( - X , - A , -`ifdef USE_POWER_PINS - VPWR , - VGND , - LVPWR, - LVGND, -`endif -); - -output X ; -input A ; -`ifdef USE_POWER_PINS -inout VPWR ; -inout VGND ; -inout LVPWR; -inout LVGND; -`endif - -sky130_fd_sc_hvl__lsbufhv2lv_1 lvlshiftdown ( -`ifdef USE_POWER_PINS - .VPWR(VPWR), - .VPB(VPWR), - - .LVPWR(LVPWR), - - .VNB(VGND), - .VGND(VGND), -`endif - .A(A), - .X(X) -); - -endmodule
diff --git a/caravel/rtl/spimemio.v b/caravel/rtl/spimemio.v deleted file mode 100644 index 0e3c95f..0000000 --- a/caravel/rtl/spimemio.v +++ /dev/null
@@ -1,753 +0,0 @@ -`default_nettype none -/* - * SPDX-FileCopyrightText: 2015 Clifford Wolf - * PicoSoC - A simple example SoC using PicoRV32 - * - * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * SPDX-License-Identifier: ISC - */ - -module spimemio_wb ( - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_adr_i, - input [31:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input wb_cyc_i, - - input wb_flash_stb_i, - input wb_cfg_stb_i, - - output wb_flash_ack_o, - output wb_cfg_ack_o, - - output [31:0] wb_flash_dat_o, - output [31:0] wb_cfg_dat_o, - - output quad_mode, - input pass_thru, - input pass_thru_csb, - input pass_thru_sck, - input pass_thru_sdi, - output pass_thru_sdo, - - output flash_csb, - output flash_clk, - - output flash_csb_oeb, - output flash_clk_oeb, - - output flash_io0_oeb, - output flash_io1_oeb, - output flash_io2_oeb, - output flash_io3_oeb, - - output flash_csb_ieb, - output flash_clk_ieb, - - output flash_io0_ieb, - output flash_io1_ieb, - output flash_io2_ieb, - output flash_io3_ieb, - - output flash_io0_do, - output flash_io1_do, - output flash_io2_do, - output flash_io3_do, - - input flash_io0_di, - input flash_io1_di, - input flash_io2_di, - input flash_io3_di - -); - wire spimem_ready; - wire [23:0] mem_addr; - wire [31:0] spimem_rdata; - wire [31:0] spimemio_cfgreg_do; - wire [3:0] cfgreg_we; - wire spimemio_cfgreg_sel; - wire valid; - wire resetn; - wire quad_mode; - - assign resetn = ~wb_rst_i; - assign valid = wb_cyc_i && wb_flash_stb_i; - assign wb_flash_ack_o = spimem_ready; - assign wb_cfg_ack_o = spimemio_cfgreg_sel; - - assign mem_addr = wb_adr_i[23:0]; - assign spimemio_cfgreg_sel = wb_cyc_i && wb_cfg_stb_i; - - assign cfgreg_we = spimemio_cfgreg_sel ? wb_sel_i & {4{wb_we_i}} : 4'b 0000; - assign wb_flash_dat_o = spimem_rdata; - assign wb_cfg_dat_o = spimemio_cfgreg_do; - - spimemio spimemio ( - .clk (wb_clk_i), - .resetn (resetn), - .valid (valid), - .ready (spimem_ready), - .addr (mem_addr), - .rdata (spimem_rdata), - - .flash_csb (flash_csb), - .flash_clk (flash_clk), - - .flash_csb_oeb (flash_csb_oeb), - .flash_clk_oeb (flash_clk_oeb), - - .flash_io0_oeb (flash_io0_oeb), - .flash_io1_oeb (flash_io1_oeb), - .flash_io2_oeb (flash_io2_oeb), - .flash_io3_oeb (flash_io3_oeb), - - .flash_csb_ieb (flash_csb_ieb), - .flash_clk_ieb (flash_clk_ieb), - - .flash_io0_ieb (flash_io0_ieb), - .flash_io1_ieb (flash_io1_ieb), - .flash_io2_ieb (flash_io2_ieb), - .flash_io3_ieb (flash_io3_ieb), - - .flash_io0_do (flash_io0_do), - .flash_io1_do (flash_io1_do), - .flash_io2_do (flash_io2_do), - .flash_io3_do (flash_io3_do), - - .flash_io0_di (flash_io0_di), - .flash_io1_di (flash_io1_di), - .flash_io2_di (flash_io2_di), - .flash_io3_di (flash_io3_di), - - .cfgreg_we(cfgreg_we), - .cfgreg_di(wb_dat_i), - .cfgreg_do(spimemio_cfgreg_do), - - .quad_mode(quad_mode), - .pass_thru(pass_thru), - .pass_thru_csb(pass_thru_csb), - .pass_thru_sck(pass_thru_sck), - .pass_thru_sdi(pass_thru_sdi), - .pass_thru_sdo(pass_thru_sdo) - ); - -endmodule - -module spimemio ( - input clk, resetn, - - input valid, - output ready, - input [23:0] addr, - output reg [31:0] rdata, - - output flash_csb, - output flash_clk, - - output flash_csb_oeb, - output flash_clk_oeb, - - output flash_io0_oeb, - output flash_io1_oeb, - output flash_io2_oeb, - output flash_io3_oeb, - - output flash_csb_ieb, - output flash_clk_ieb, - - output flash_io0_ieb, - output flash_io1_ieb, - output flash_io2_ieb, - output flash_io3_ieb, - - output flash_io0_do, - output flash_io1_do, - output flash_io2_do, - output flash_io3_do, - - input flash_io0_di, - input flash_io1_di, - input flash_io2_di, - input flash_io3_di, - - input [3:0] cfgreg_we, - input [31:0] cfgreg_di, - output [31:0] cfgreg_do, - - output quad_mode, - - input pass_thru, - input pass_thru_csb, - input pass_thru_sck, - input pass_thru_sdi, - output pass_thru_sdo -); - reg xfer_resetn; - reg din_valid; - wire din_ready; - reg [7:0] din_data; - reg [3:0] din_tag; - reg din_cont; - reg din_qspi; - reg din_ddr; - reg din_rd; - - wire dout_valid; - wire [7:0] dout_data; - wire [3:0] dout_tag; - wire quad_mode; - - reg [23:0] buffer; - - reg [23:0] rd_addr; - reg rd_valid; - reg rd_wait; - reg rd_inc; - - assign ready = valid && (addr == rd_addr) && rd_valid; - wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid; - - reg softreset; - - reg config_en; // cfgreg[31] - reg config_ddr; // cfgreg[22] - reg config_qspi; // cfgreg[21] - reg config_cont; // cfgreg[20] - reg [3:0] config_dummy; // cfgreg[19:16] - reg [3:0] config_oe; // cfgreg[11:8] - reg config_csb; // cfgreg[5] - reg config_clk; // cfgref[4] - reg [3:0] config_do; // cfgreg[3:0] - - assign cfgreg_do[31] = config_en; - assign cfgreg_do[30:23] = 0; - assign cfgreg_do[22] = config_ddr; - assign cfgreg_do[21] = config_qspi; - assign cfgreg_do[20] = config_cont; - assign cfgreg_do[19:16] = config_dummy; - assign cfgreg_do[15:12] = 0; - assign cfgreg_do[11:8] = {~flash_io3_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb}; - assign cfgreg_do[7:6] = 0; - assign cfgreg_do[5] = flash_csb; - assign cfgreg_do[4] = flash_clk; - assign cfgreg_do[3:0] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di}; - - always @(posedge clk) begin - softreset <= !config_en || cfgreg_we; - if (!resetn) begin - softreset <= 1; - config_en <= 1; - config_csb <= 0; - config_clk <= 0; - config_oe <= 0; - config_do <= 0; - config_ddr <= 0; - config_qspi <= 0; - config_cont <= 0; - config_dummy <= 8; - end else begin - if (cfgreg_we[0]) begin - config_csb <= cfgreg_di[5]; - config_clk <= cfgreg_di[4]; - config_do <= cfgreg_di[3:0]; - end - if (cfgreg_we[1]) begin - config_oe <= cfgreg_di[11:8]; - end - if (cfgreg_we[2]) begin - config_ddr <= cfgreg_di[22]; - config_qspi <= cfgreg_di[21]; - config_cont <= cfgreg_di[20]; - config_dummy <= cfgreg_di[19:16]; - end - if (cfgreg_we[3]) begin - config_en <= cfgreg_di[31]; - end - end - end - - wire xfer_csb; - wire xfer_clk; - - wire xfer_io0_oe; - wire xfer_io1_oe; - wire xfer_io2_oe; - wire xfer_io3_oe; - - wire xfer_io0_do; - wire xfer_io1_do; - wire xfer_io2_do; - wire xfer_io3_do; - - reg xfer_io0_90; - reg xfer_io1_90; - reg xfer_io2_90; - reg xfer_io3_90; - - always @(negedge clk) begin - xfer_io0_90 <= xfer_io0_do; - xfer_io1_90 <= xfer_io1_do; - xfer_io2_90 <= xfer_io2_do; - xfer_io3_90 <= xfer_io3_do; - end - - wire pass_thru; - wire pass_thru_csb; - wire pass_thru_sck; - wire pass_thru_sdi; - wire pass_thru_sdo; - - assign quad_mode = config_qspi; - - assign flash_csb = (pass_thru) ? pass_thru_csb : (config_en ? xfer_csb : config_csb); - assign flash_clk = (pass_thru) ? pass_thru_sck : (config_en ? xfer_clk : config_clk); - - assign flash_csb_oeb = (pass_thru) ? 1'b0 : (~resetn ? 1'b1 : 1'b0); - assign flash_clk_oeb = (pass_thru) ? 1'b0 : (~resetn ? 1'b1 : 1'b0); - - assign flash_io0_oeb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : (config_en ? ~xfer_io0_oe : ~config_oe[0]); - assign flash_io1_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io1_oe : ~config_oe[1]); - assign flash_io2_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io2_oe : ~config_oe[2]); - assign flash_io3_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io3_oe : ~config_oe[3]); - assign flash_csb_ieb = 1'b1; /* Always disabled */ - assign flash_clk_ieb = 1'b1; /* Always disabled */ - - assign flash_io0_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io0_oe : config_oe[0]); - assign flash_io1_ieb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]); - assign flash_io2_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io2_oe : config_oe[2]); - assign flash_io3_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io3_oe : config_oe[3]); - - assign flash_io0_do = pass_thru ? pass_thru_sdi : (config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0]); - assign flash_io1_do = config_en ? (config_ddr ? xfer_io1_90 : xfer_io1_do) : config_do[1]; - assign flash_io2_do = config_en ? (config_ddr ? xfer_io2_90 : xfer_io2_do) : config_do[2]; - assign flash_io3_do = config_en ? (config_ddr ? xfer_io3_90 : xfer_io3_do) : config_do[3]; - assign pass_thru_sdo = pass_thru ? flash_io1_di : 1'b0; - - wire xfer_dspi = din_ddr && !din_qspi; - wire xfer_ddr = din_ddr && din_qspi; - - spimemio_xfer xfer ( - .clk (clk ), - .resetn (resetn ), - .xfer_resetn (xfer_resetn ), - .din_valid (din_valid ), - .din_ready (din_ready ), - .din_data (din_data ), - .din_tag (din_tag ), - .din_cont (din_cont ), - .din_dspi (xfer_dspi ), - .din_qspi (din_qspi ), - .din_ddr (xfer_ddr ), - .din_rd (din_rd ), - .dout_valid (dout_valid ), - .dout_data (dout_data ), - .dout_tag (dout_tag ), - .flash_csb (xfer_csb ), - .flash_clk (xfer_clk ), - .flash_io0_oe (xfer_io0_oe ), - .flash_io1_oe (xfer_io1_oe ), - .flash_io2_oe (xfer_io2_oe ), - .flash_io3_oe (xfer_io3_oe ), - .flash_io0_do (xfer_io0_do ), - .flash_io1_do (xfer_io1_do ), - .flash_io2_do (xfer_io2_do ), - .flash_io3_do (xfer_io3_do ), - .flash_io0_di (flash_io0_di), - .flash_io1_di (flash_io1_di), - .flash_io2_di (flash_io2_di), - .flash_io3_di (flash_io3_di) - ); - - reg [3:0] state; - - always @(posedge clk) begin - xfer_resetn <= 1; - din_valid <= 0; - - if (!resetn || softreset) begin - state <= 0; - xfer_resetn <= 0; - rd_valid <= 0; - din_tag <= 0; - din_cont <= 0; - din_qspi <= 0; - din_ddr <= 0; - din_rd <= 0; - end else begin - if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data; - if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data; - if (dout_valid && dout_tag == 3) buffer[23:16] <= dout_data; - if (dout_valid && dout_tag == 4) begin - rdata <= {dout_data, buffer}; - rd_addr <= rd_inc ? rd_addr + 4 : addr; - rd_valid <= 1; - rd_wait <= rd_inc; - rd_inc <= 1; - end - - if (valid) - rd_wait <= 0; - - case (state) - 0: begin - din_valid <= 1; - din_data <= 8'h ff; - din_tag <= 0; - if (din_ready) begin - din_valid <= 0; - state <= 1; - end - end - 1: begin - if (dout_valid) begin - xfer_resetn <= 0; - state <= 2; - end - end - 2: begin - din_valid <= 1; - din_data <= 8'h ab; - din_tag <= 0; - if (din_ready) begin - din_valid <= 0; - state <= 3; - end - end - 3: begin - if (dout_valid) begin - xfer_resetn <= 0; - state <= 4; - end - end - 4: begin - rd_inc <= 0; - din_valid <= 1; - din_tag <= 0; - case ({config_ddr, config_qspi}) - 2'b11: din_data <= 8'h ED; - 2'b01: din_data <= 8'h EB; - 2'b10: din_data <= 8'h BB; - 2'b00: din_data <= 8'h 03; - endcase - if (din_ready) begin - din_valid <= 0; - state <= 5; - end - end - 5: begin - if (valid && !ready) begin - din_valid <= 1; - din_tag <= 0; - din_data <= addr[23:16]; - din_qspi <= config_qspi; - din_ddr <= config_ddr; - if (din_ready) begin - din_valid <= 0; - state <= 6; - end - end - end - 6: begin - din_valid <= 1; - din_tag <= 0; - din_data <= addr[15:8]; - if (din_ready) begin - din_valid <= 0; - state <= 7; - end - end - 7: begin - din_valid <= 1; - din_tag <= 0; - din_data <= addr[7:0]; - if (din_ready) begin - din_valid <= 0; - din_data <= 0; - state <= config_qspi || config_ddr ? 8 : 9; - end - end - 8: begin - din_valid <= 1; - din_tag <= 0; - din_data <= config_cont ? 8'h A5 : 8'h FF; - if (din_ready) begin - din_rd <= 1; - din_data <= config_dummy; - din_valid <= 0; - state <= 9; - end - end - 9: begin - din_valid <= 1; - din_tag <= 1; - if (din_ready) begin - din_valid <= 0; - state <= 10; - end - end - 10: begin - din_valid <= 1; - din_data <= 8'h 00; - din_tag <= 2; - if (din_ready) begin - din_valid <= 0; - state <= 11; - end - end - 11: begin - din_valid <= 1; - din_tag <= 3; - if (din_ready) begin - din_valid <= 0; - state <= 12; - end - end - 12: begin - if (!rd_wait || valid) begin - din_valid <= 1; - din_tag <= 4; - if (din_ready) begin - din_valid <= 0; - state <= 9; - end - end - end - endcase - - if (jump) begin - rd_inc <= 0; - rd_valid <= 0; - xfer_resetn <= 0; - if (config_cont) begin - state <= 5; - end else begin - state <= 4; - din_qspi <= 0; - din_ddr <= 0; - end - din_rd <= 0; - end - end - end -endmodule - -module spimemio_xfer ( - input clk, resetn, xfer_resetn, - - input din_valid, - output din_ready, - input [7:0] din_data, - input [3:0] din_tag, - input din_cont, - input din_dspi, - input din_qspi, - input din_ddr, - input din_rd, - - output dout_valid, - output [7:0] dout_data, - output [3:0] dout_tag, - - output reg flash_csb, - output reg flash_clk, - - output reg flash_io0_oe, - output reg flash_io1_oe, - output reg flash_io2_oe, - output reg flash_io3_oe, - - output reg flash_io0_do, - output reg flash_io1_do, - output reg flash_io2_do, - output reg flash_io3_do, - - input flash_io0_di, - input flash_io1_di, - input flash_io2_di, - input flash_io3_di -); - reg [7:0] obuffer; - reg [7:0] ibuffer; - - reg [3:0] count; - reg [3:0] dummy_count; - - reg xfer_cont; - reg xfer_dspi; - reg xfer_qspi; - reg xfer_ddr; - reg xfer_ddr_q; - reg xfer_rd; - reg [3:0] xfer_tag; - reg [3:0] xfer_tag_q; - - reg [7:0] next_obuffer; - reg [7:0] next_ibuffer; - reg [3:0] next_count; - - reg fetch; - reg next_fetch; - reg last_fetch; - - always @(posedge clk) begin - xfer_ddr_q <= xfer_ddr; - xfer_tag_q <= xfer_tag; - end - - assign din_ready = din_valid && xfer_resetn && next_fetch; - - assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && xfer_resetn; - assign dout_data = ibuffer; - assign dout_tag = xfer_tag_q; - - always @* begin - flash_io0_oe = 0; - flash_io1_oe = 0; - flash_io2_oe = 0; - flash_io3_oe = 0; - - flash_io0_do = 0; - flash_io1_do = 0; - flash_io2_do = 0; - flash_io3_do = 0; - - next_obuffer = obuffer; - next_ibuffer = ibuffer; - next_count = count; - next_fetch = 0; - - if (dummy_count == 0) begin - casez ({xfer_ddr, xfer_qspi, xfer_dspi}) - 3'b 000: begin - flash_io0_oe = 1; - flash_io0_do = obuffer[7]; - - if (flash_clk) begin - next_obuffer = {obuffer[6:0], 1'b 0}; - next_count = count - |count; - end else begin - next_ibuffer = {ibuffer[6:0], flash_io1_di}; - end - - next_fetch = (next_count == 0); - end - 3'b 01?: begin - flash_io0_oe = !xfer_rd; - flash_io1_oe = !xfer_rd; - flash_io2_oe = !xfer_rd; - flash_io3_oe = !xfer_rd; - - flash_io0_do = obuffer[4]; - flash_io1_do = obuffer[5]; - flash_io2_do = obuffer[6]; - flash_io3_do = obuffer[7]; - - if (flash_clk) begin - next_obuffer = {obuffer[3:0], 4'b 0000}; - next_count = count - {|count, 2'b00}; - end else begin - next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di}; - end - - next_fetch = (next_count == 0); - end - 3'b 11?: begin - flash_io0_oe = !xfer_rd; - flash_io1_oe = !xfer_rd; - flash_io2_oe = !xfer_rd; - flash_io3_oe = !xfer_rd; - - flash_io0_do = obuffer[4]; - flash_io1_do = obuffer[5]; - flash_io2_do = obuffer[6]; - flash_io3_do = obuffer[7]; - - next_obuffer = {obuffer[3:0], 4'b 0000}; - next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di}; - next_count = count - {|count, 2'b00}; - - next_fetch = (next_count == 0); - end - 3'b ??1: begin - flash_io0_oe = !xfer_rd; - flash_io1_oe = !xfer_rd; - - flash_io0_do = obuffer[6]; - flash_io1_do = obuffer[7]; - - if (flash_clk) begin - next_obuffer = {obuffer[5:0], 2'b 00}; - next_count = count - {|count, 1'b0}; - end else begin - next_ibuffer = {ibuffer[5:0], flash_io1_di, flash_io0_di}; - end - - next_fetch = (next_count == 0); - end - endcase - end - end - - always @(posedge clk) begin - if (!resetn || !xfer_resetn) begin - fetch <= 1; - last_fetch <= 1; - flash_csb <= 1; - flash_clk <= 0; - count <= 0; - dummy_count <= 0; - xfer_tag <= 0; - xfer_cont <= 0; - xfer_dspi <= 0; - xfer_qspi <= 0; - xfer_ddr <= 0; - xfer_rd <= 0; - end else begin - fetch <= next_fetch; - last_fetch <= xfer_ddr ? fetch : 1; - if (dummy_count) begin - flash_clk <= !flash_clk && !flash_csb; - dummy_count <= dummy_count - flash_clk; - end else - if (count) begin - flash_clk <= !flash_clk && !flash_csb; - obuffer <= next_obuffer; - ibuffer <= next_ibuffer; - count <= next_count; - end - if (din_valid && din_ready) begin - flash_csb <= 0; - flash_clk <= 0; - - count <= 8; - dummy_count <= din_rd ? din_data : 0; - obuffer <= din_data; - - xfer_tag <= din_tag; - xfer_cont <= din_cont; - xfer_dspi <= din_dspi; - xfer_qspi <= din_qspi; - xfer_ddr <= din_ddr; - xfer_rd <= din_rd; - end - end - end -endmodule - -`default_nettype wire
diff --git a/caravel/rtl/sram_1rw1r_32_256_8_sky130.v b/caravel/rtl/sram_1rw1r_32_256_8_sky130.v deleted file mode 100644 index cd7cc59..0000000 --- a/caravel/rtl/sram_1rw1r_32_256_8_sky130.v +++ /dev/null
@@ -1,133 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -// OpenRAM SRAM model -// Words: 256 -// Word size: 32 -// Write size: 8 - -module sram_1rw1r_32_256_8_sky130( -`ifdef USE_POWER_PINS - vdd, - gnd, -`endif -// Port 0: RW - clk0,csb0,web0,wmask0,addr0,din0,dout0, -// Port 1: R - clk1,csb1,addr1,dout1 - ); - - parameter NUM_WMASKS = 4 ; - parameter DATA_WIDTH = 32 ; - parameter ADDR_WIDTH = 8 ; - parameter RAM_DEPTH = 1 << ADDR_WIDTH; - // FIXME: This delay is arbitrary. - parameter DELAY = 3 ; - -`ifdef USE_POWER_PINS - inout vdd; - inout gnd; -`endif - input clk0; // clock - input csb0; // active low chip select - input web0; // active low write control - input [NUM_WMASKS-1:0] wmask0; // write mask - input [ADDR_WIDTH-1:0] addr0; - input [DATA_WIDTH-1:0] din0; - output [DATA_WIDTH-1:0] dout0; - input clk1; // clock - input csb1; // active low chip select - input [ADDR_WIDTH-1:0] addr1; - output [DATA_WIDTH-1:0] dout1; - - reg csb0_reg; - reg web0_reg; - reg [NUM_WMASKS-1:0] wmask0_reg; - reg [ADDR_WIDTH-1:0] addr0_reg; - reg [DATA_WIDTH-1:0] din0_reg; - reg [DATA_WIDTH-1:0] dout0; - - // All inputs are registers - always @(posedge clk0) - begin - csb0_reg = csb0; - web0_reg = web0; - wmask0_reg = wmask0; - addr0_reg = addr0; - din0_reg = din0; - dout0 = #(DELAY) 32'bx; -`ifdef DBG - if ( !csb0_reg && web0_reg ) - $display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]); - if ( !csb0_reg && !web0_reg ) - $display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg); -`endif - end - - reg csb1_reg; - reg [ADDR_WIDTH-1:0] addr1_reg; - reg [DATA_WIDTH-1:0] dout1; - - // All inputs are registers - always @(posedge clk1) - begin - csb1_reg = csb1; - addr1_reg = addr1; -`ifdef DBG - if (!csb0 && !web0 && !csb1 && (addr0 == addr1)) - $display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1); - dout1 = 32'bx; - if ( !csb1_reg ) - $display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]); -`endif - end - -reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; - - // Memory Write Block Port 0 - // Write Operation : When web0 = 0, csb0 = 0 - always @ (negedge clk0) - begin : MEM_WRITE0 - if ( !csb0_reg && !web0_reg ) begin - if (wmask0_reg[0]) - mem[addr0_reg][7:0] = din0_reg[7:0]; - if (wmask0_reg[1]) - mem[addr0_reg][15:8] = din0_reg[15:8]; - if (wmask0_reg[2]) - mem[addr0_reg][23:16] = din0_reg[23:16]; - if (wmask0_reg[3]) - mem[addr0_reg][31:24] = din0_reg[31:24]; - end - end - - // Memory Read Block Port 0 - // Read Operation : When web0 = 1, csb0 = 0 - always @ (negedge clk0) - begin : MEM_READ0 - if (!csb0_reg && web0_reg) - dout0 <= #(DELAY) mem[addr0_reg]; - end - - // Memory Read Block Port 1 - // Read Operation : When web1 = 1, csb1 = 0 - always @ (negedge clk1) - begin : MEM_READ1 - if (!csb1_reg) - dout1 <= #(DELAY) mem[addr1_reg]; - end - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/storage.v b/caravel/rtl/storage.v deleted file mode 100644 index a3c1b14..0000000 --- a/caravel/rtl/storage.v +++ /dev/null
@@ -1,107 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none - -module storage ( -`ifdef USE_POWER_PINS - input wire VPWR, - input wire VGND, -`endif - // MGMT_AREA R/W Interface - input mgmt_clk, - input [`RAM_BLOCKS-1:0] mgmt_ena, - input [`RAM_BLOCKS-1:0] mgmt_wen, // not shared - input [(`RAM_BLOCKS*4)-1:0] mgmt_wen_mask, // not shared - input [7:0] mgmt_addr, - input [31:0] mgmt_wdata, - output [(`RAM_BLOCKS*32)-1:0] mgmt_rdata, - - // MGMT_AREA RO Interface - input mgmt_ena_ro, - input [7:0] mgmt_addr_ro, - output [31:0] mgmt_rdata_ro -); - - // Add buf_4 -> 2x buf_8 to suuply clock to each block. - wire mgmt_clk_buf; - sky130_fd_sc_hd__buf_4 BUF_4 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .A(mgmt_clk), - .X(mgmt_clk_buf) - ); - - wire mgmt_clk_sram0; - sky130_fd_sc_hd__buf_8 BUF0_8 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .A(mgmt_clk_buf), - .X(mgmt_clk_sram0) - ); - - wire mgmt_clk_sram1; - sky130_fd_sc_hd__buf_8 BUF1_8 ( - `ifdef USE_POWER_PINS - .VPWR(VPWR), - .VGND(VGND), - .VPB(VPWR), - .VNB(VGND), - `endif - .A(mgmt_clk_buf), - .X(mgmt_clk_sram1) - ); - - sram_1rw1r_32_256_8_sky130 SRAM_0 ( - // MGMT R/W port - .clk0(mgmt_clk_sram0), - .csb0(mgmt_ena[0]), - .web0(mgmt_wen[0]), - .wmask0(mgmt_wen_mask[3:0]), - .addr0(mgmt_addr), - .din0(mgmt_wdata), - .dout0(mgmt_rdata[31:0]), - // MGMT RO port - .clk1(mgmt_clk_sram0), - .csb1(mgmt_ena_ro), - .addr1(mgmt_addr_ro), - .dout1(mgmt_rdata_ro) - ); - - sram_1rw1r_32_256_8_sky130 SRAM_1 ( - // MGMT R/W port - .clk0(mgmt_clk_sram1), - .csb0(mgmt_ena[1]), - .web0(mgmt_wen[1]), - .wmask0(mgmt_wen_mask[7:4]), - .addr0(mgmt_addr), - .din0(mgmt_wdata), - .dout0(mgmt_rdata[63:32]), - .clk1(1'b0), - .csb1(1'b1), - .addr1(8'b0), - .dout1() - ); - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/storage_bridge_wb.v b/caravel/rtl/storage_bridge_wb.v deleted file mode 100644 index 0f24321..0000000 --- a/caravel/rtl/storage_bridge_wb.v +++ /dev/null
@@ -1,112 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -module storage_bridge_wb ( - // MGMT_AREA R/W WB Interface - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_adr_i, - input [31:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input wb_cyc_i, - input [1:0] wb_stb_i, - output reg [1:0] wb_ack_o, - output reg [31:0] wb_rw_dat_o, - - // MGMT_AREA RO WB Interface - output [31:0] wb_ro_dat_o, - - // MGMT Area native memory interface - output [`RAM_BLOCKS-1:0] mgmt_ena, - output [(`RAM_BLOCKS*4)-1:0] mgmt_wen_mask, - output [`RAM_BLOCKS-1:0] mgmt_wen, - output [7:0] mgmt_addr, - output [31:0] mgmt_wdata, - input [(`RAM_BLOCKS*32)-1:0] mgmt_rdata, - - // MGMT_AREA RO Interface - output mgmt_ena_ro, - output [7:0] mgmt_addr_ro, - input [31:0] mgmt_rdata_ro -); - parameter [(`RAM_BLOCKS*24)-1:0] RW_BLOCKS_ADR = { - {24'h 10_0000}, - {24'h 00_0000} - }; - - parameter [23:0] RO_BLOCKS_ADR = { - {24'h 20_0000} - }; - - parameter ADR_MASK = 24'h FF_0000; - - wire [1:0] valid; - wire [1:0] wen; - wire [7:0] wen_mask; - - assign valid = {2{wb_cyc_i}} & wb_stb_i; - assign wen = wb_we_i & valid; - assign wen_mask = wb_sel_i & {{4{wen[1]}}, {4{wen[0]}}}; - - // Ack generation - reg [1:0] wb_ack_read; - - always @(posedge wb_clk_i) begin - if (wb_rst_i == 1'b 1) begin - wb_ack_read <= 2'b0; - wb_ack_o <= 2'b0; - end else begin - wb_ack_o <= wb_we_i? (valid & ~wb_ack_o): wb_ack_read; - wb_ack_read <= (valid & ~wb_ack_o) & ~wb_ack_read; - end - end - - // Address decoding - wire [`RAM_BLOCKS-1: 0] rw_sel; - wire ro_sel; - - genvar iS; - generate - for (iS = 0; iS < `RAM_BLOCKS; iS = iS + 1) begin - assign rw_sel[iS] = - ((wb_adr_i[23:0] & ADR_MASK) == RW_BLOCKS_ADR[(iS+1)*24-1:iS*24]); - end - endgenerate - - // Management R/W interface - assign mgmt_ena = valid[0] ? ~rw_sel : {`RAM_BLOCKS{1'b1}}; - assign mgmt_wen = ~{`RAM_BLOCKS{wen[0]}}; - assign mgmt_wen_mask = {`RAM_BLOCKS{wen_mask[3:0]}}; - assign mgmt_addr = wb_adr_i[9:2]; - assign mgmt_wdata = wb_dat_i[31:0]; - - integer i; - always @(*) begin - wb_rw_dat_o = {32{1'b0}}; - for (i=0; i<(`RAM_BLOCKS*32); i=i+1) - wb_rw_dat_o[i%32] = wb_rw_dat_o[i%32] | (rw_sel[i/32] & mgmt_rdata[i]); - end - - // RO Interface - assign ro_sel = ((wb_adr_i[23:0] & ADR_MASK) == RO_BLOCKS_ADR); - assign mgmt_ena_ro = valid[1] ? ~ro_sel : 1'b1; - assign mgmt_addr_ro = wb_adr_i[9:2]; - assign wb_ro_dat_o = mgmt_rdata_ro; - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/sysctrl.v b/caravel/rtl/sysctrl.v deleted file mode 100644 index c18979e..0000000 --- a/caravel/rtl/sysctrl.v +++ /dev/null
@@ -1,180 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -module sysctrl_wb #( - parameter BASE_ADR = 32'h2F00_0000, - parameter PWRGOOD = 8'h00, - parameter CLK_OUT = 8'h04, - parameter TRAP_OUT = 8'h08, - parameter IRQ_SRC = 8'h0c -) ( - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_dat_i, - input [31:0] wb_adr_i, - input [3:0] wb_sel_i, - input wb_cyc_i, - input wb_stb_i, - input wb_we_i, - - output [31:0] wb_dat_o, - output wb_ack_o, - - input usr1_vcc_pwrgood, - input usr2_vcc_pwrgood, - input usr1_vdd_pwrgood, - input usr2_vdd_pwrgood, - output clk1_output_dest, - output clk2_output_dest, - output trap_output_dest, - output irq_7_inputsrc, - output irq_8_inputsrc - -); - - wire resetn; - wire valid; - wire ready; - wire [3:0] iomem_we; - - assign resetn = ~wb_rst_i; - assign valid = wb_stb_i && wb_cyc_i; - - assign iomem_we = wb_sel_i & {4{wb_we_i}}; - assign wb_ack_o = ready; - - sysctrl #( - .BASE_ADR(BASE_ADR), - .PWRGOOD(PWRGOOD), - .CLK_OUT(CLK_OUT), - .TRAP_OUT(TRAP_OUT), - .IRQ_SRC(IRQ_SRC) - ) sysctrl ( - .clk(wb_clk_i), - .resetn(resetn), - - .iomem_addr(wb_adr_i), - .iomem_valid(valid), - .iomem_wstrb(iomem_we), - .iomem_wdata(wb_dat_i), - .iomem_rdata(wb_dat_o), - .iomem_ready(ready), - - .usr1_vcc_pwrgood(usr1_vcc_pwrgood), - .usr2_vcc_pwrgood(usr2_vcc_pwrgood), - .usr1_vdd_pwrgood(usr1_vdd_pwrgood), - .usr2_vdd_pwrgood(usr2_vdd_pwrgood), - .clk1_output_dest(clk1_output_dest), - .clk2_output_dest(clk2_output_dest), - .trap_output_dest(trap_output_dest), - .irq_8_inputsrc(irq_8_inputsrc), - .irq_7_inputsrc(irq_7_inputsrc) - ); - -endmodule - -module sysctrl #( - parameter BASE_ADR = 32'h2300_0000, - parameter PWRGOOD = 8'h00, - parameter CLK_OUT = 8'h04, - parameter TRAP_OUT = 8'h08, - parameter IRQ_SRC = 8'h0c -) ( - input clk, - input resetn, - - input [31:0] iomem_addr, - input iomem_valid, - input [3:0] iomem_wstrb, - input [31:0] iomem_wdata, - output reg [31:0] iomem_rdata, - output reg iomem_ready, - - input usr1_vcc_pwrgood, - input usr2_vcc_pwrgood, - input usr1_vdd_pwrgood, - input usr2_vdd_pwrgood, - output clk1_output_dest, - output clk2_output_dest, - output trap_output_dest, - output irq_7_inputsrc, - output irq_8_inputsrc -); - - reg clk1_output_dest; - reg clk2_output_dest; - reg trap_output_dest; - reg irq_7_inputsrc; - reg irq_8_inputsrc; - - wire usr1_vcc_pwrgood; - wire usr2_vcc_pwrgood; - wire usr1_vdd_pwrgood; - wire usr2_vdd_pwrgood; - - wire pwrgood_sel; - wire clk_out_sel; - wire trap_out_sel; - wire irq_sel; - - assign pwrgood_sel = (iomem_addr[7:0] == PWRGOOD); - assign clk_out_sel = (iomem_addr[7:0] == CLK_OUT); - assign trap_out_sel = (iomem_addr[7:0] == TRAP_OUT); - assign irq_sel = (iomem_addr[7:0] == IRQ_SRC); - - always @(posedge clk) begin - if (!resetn) begin - clk1_output_dest <= 0; - clk2_output_dest <= 0; - trap_output_dest <= 0; - irq_7_inputsrc <= 0; - irq_8_inputsrc <= 0; - end else begin - iomem_ready <= 0; - if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin - iomem_ready <= 1'b 1; - - if (pwrgood_sel) begin - iomem_rdata <= {28'd0, usr2_vdd_pwrgood, usr1_vdd_pwrgood, - usr2_vcc_pwrgood, usr1_vcc_pwrgood}; - // These are read-only bits; no write behavior on wstrb. - - end else if (clk_out_sel) begin - iomem_rdata <= {30'd0, clk2_output_dest, clk1_output_dest}; - if (iomem_wstrb[0]) begin - clk1_output_dest <= iomem_wdata[0]; - clk2_output_dest <= iomem_wdata[1]; - end - - end else if (trap_out_sel) begin - iomem_rdata <= {31'd0, trap_output_dest}; - if (iomem_wstrb[0]) - trap_output_dest <= iomem_wdata[0]; - - end else if (irq_sel) begin - iomem_rdata <= {30'd0, irq_8_inputsrc, irq_7_inputsrc}; - if (iomem_wstrb[0]) begin - irq_7_inputsrc <= iomem_wdata[0]; - irq_8_inputsrc <= iomem_wdata[1]; - end - end - end - end - end - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/user_id_programming.v b/caravel/rtl/user_id_programming.v deleted file mode 100644 index 873bbce..0000000 --- a/caravel/rtl/user_id_programming.v +++ /dev/null
@@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -// This module represents an unprogrammed mask revision -// block that is configured with via programming on the -// chip top level. This value is passed to the block as -// a parameter - -module user_id_programming #( - parameter [ 0:0] USER_PROJECT_ID = 32'h0 -) ( -`ifdef USE_POWER_PINS - inout VPWR, - inout VGND, -`endif - output [31:0] mask_rev -); - wire [31:0] mask_rev; - wire [31:0] user_proj_id_high; - wire [31:0] user_proj_id_low; - - // For the mask revision input, use an array of digital constant logic cells - - sky130_fd_sc_hd__conb_1 mask_rev_value [31:0] ( -`ifdef USE_POWER_PINS - .VPWR(VPWR), - .VPB(VPWR), - .VNB(VGND), - .VGND(VGND), -`endif - .HI(user_proj_id_high), - .LO(user_proj_id_low) - ); - - genvar i; - generate - for (i = 0; i < 32; i = i+1) begin - assign mask_rev[i] = (USER_PROJECT_ID & (32'h01 << i)) ? - user_proj_id_high[i] : user_proj_id_low[i]; - end - endgenerate - -endmodule -`default_nettype wire
diff --git a/caravel/rtl/wb_intercon.v b/caravel/rtl/wb_intercon.v deleted file mode 100644 index 7ebce83..0000000 --- a/caravel/rtl/wb_intercon.v +++ /dev/null
@@ -1,74 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// 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 - -`default_nettype none -module wb_intercon #( - parameter DW = 32, // Data Width - parameter AW = 32, // Address Width - parameter NS = 6 // Number of Slaves -) ( - // Master Interface - input [AW-1:0] wbm_adr_i, - input wbm_stb_i, - - output reg [DW-1:0] wbm_dat_o, - output wbm_ack_o, - - // Slave Interface - input [NS*DW-1:0] wbs_dat_i, - input [NS-1:0] wbs_ack_i, - output [NS-1:0] wbs_stb_o -); - parameter [NS*AW-1:0] ADR_MASK = { // Page & Sub-page bits - {8'hFF, {24{1'b0}} }, - {8'hFF, {24{1'b0}} }, - {8'hFF, {24{1'b0}} }, - {8'hFF, {24{1'b0}} }, - {8'hFF, {24{1'b0}} }, - {8'hFF, {24{1'b0}} } - }; - parameter [NS*AW-1:0] SLAVE_ADR = { - { 32'h2800_0000 }, // Flash Configuration Register - { 32'h2200_0000 }, // System Control - { 32'h2100_0000 }, // GPIOs - { 32'h2000_0000 }, // UART - { 32'h1000_0000 }, // Flash - { 32'h0000_0000 } // RAM - }; - - wire [NS-1: 0] slave_sel; - - // Address decoder - genvar iS; - generate - for (iS = 0; iS < NS; iS = iS + 1) begin - assign slave_sel[iS] = - ((wbm_adr_i & ADR_MASK[(iS+1)*AW-1:iS*AW]) == SLAVE_ADR[(iS+1)*AW-1:iS*AW]); - end - endgenerate - - // Data-out Assignment - assign wbm_ack_o = |(wbs_ack_i & slave_sel); - assign wbs_stb_o = {NS{wbm_stb_i}} & slave_sel; - - integer i; - always @(*) begin - wbm_dat_o = {DW{1'b0}}; - for (i=0; i<(NS*DW); i=i+1) - wbm_dat_o[i%DW] = wbm_dat_o[i%DW] | (slave_sel[i/DW] & wbs_dat_i[i]); - end - -endmodule -`default_nettype wire