dakies/OSS_Verilog huggingface dataset:
module pll(
	input  clock_in,
	output clock_out,
	output locked
	);

SB_PLL40_CORE #(
		.FEEDBACK_PATH("SIMPLE"),
		.DIVR(4'b0000),		// DIVR =  0
		.DIVF(7'b1010110),	// DIVF = 86
		.DIVQ(3'b100),		// DIVQ =  4
		.FILTER_RANGE(3'b001)	// FILTER_RANGE = 1
	) uut (
		.LOCK(locked),
		.RESETB(1'b1),
		.BYPASS(1'b0),
		.REFERENCECLK(clock_in),
		.PLLOUTCORE(clock_out)
		);

endmodule
module lfsr(
   output [N-1:0] rnd
);

parameter N = 63;

lcell lc0(~(rnd[N - 1] ^ rnd[N - 3] ^ rnd[N - 4] ^ rnd[N - 6] ^ rnd[N - 10]), rnd[0]);
generate 
	genvar i;
	for (i = 0; i <= N - 2; i = i + 1) begin : lcn
		lcell lc(rnd[i], rnd[i + 1]);
	end
endgenerate

endmodule
module pll (
		input  wire  refclk,   //  refclk.clk
		input  wire  rst,      //   reset.reset
		output wire  outclk_0, // outclk0.clk
		output wire  outclk_1, // outclk1.clk
		output wire  locked    //  locked.export
	);

	pll_0002 pll_inst (
		.refclk   (refclk),   //  refclk.clk
		.rst      (rst),      //   reset.reset
		.outclk_0 (outclk_0), // outclk0.clk
		.outclk_1 (outclk_1), // outclk1.clk
		.locked   (locked)    //  locked.export
	);

endmodule
module gray_count
(
	input   [5:0]   b,
  	output  [5:0]   g
);
  assign g = b ^ (b >> 1);

endmodule
module dffen_2seg
(
    input wire clk, reset,
    input wire en,
    input wire d,
    output reg q
);
// s i g n a l d e c l a r a t i o n
reg data, nextdata;
// body
// D FF
always @(posedge clk , posedge reset)
if (reset)
    data <= 1'b0;
else
    data <= nextdata;

always @*
if(en)
    nextdata = d;
else
    nextdata = data;
// o u t p u t l o g i c
always @*
    q = data;

endmodule
module  pll_audio_0002(

	// interface 'refclk'
	input wire refclk,

	// interface 'reset'
	input wire rst,

	// interface 'outclk0'
	output wire outclk_0,

	// interface 'locked'
	output wire locked
);

	altera_pll #(
		.fractional_vco_multiplier("true"),
		.reference_clock_frequency("50.0 MHz"),
		.operation_mode("direct"),
		.number_of_clocks(1),
		.output_clock_frequency0("24.576000 MHz"),
		.phase_shift0("0 ps"),
		.duty_cycle0(50),
		.output_clock_frequency1("0 MHz"),
		.phase_shift1("0 ps"),
		.duty_cycle1(50),
		.output_clock_frequency2("0 MHz"),
		.phase_shift2("0 ps"),
		.duty_cycle2(50),
		.output_clock_frequency3("0 MHz"),
		.phase_shift3("0 ps"),
		.duty_cycle3(50),
		.output_clock_frequency4("0 MHz"),
		.phase_shift4("0 ps"),
		.duty_cycle4(50),
		.output_clock_frequency5("0 MHz"),
		.phase_shift5("0 ps"),
		.duty_cycle5(50),
		.output_clock_frequency6("0 MHz"),
		.phase_shift6("0 ps"),
		.duty_cycle6(50),
		.output_clock_frequency7("0 MHz"),
		.phase_shift7("0 ps"),
		.duty_cycle7(50),
		.output_clock_frequency8("0 MHz"),
		.phase_shift8("0 ps"),
		.duty_cycle8(50),
		.output_clock_frequency9("0 MHz"),
		.phase_shift9("0 ps"),
		.duty_cycle9(50),
		.output_clock_frequency10("0 MHz"),
		.phase_shift10("0 ps"),
		.duty_cycle10(50),
		.output_clock_frequency11("0 MHz"),
		.phase_shift11("0 ps"),
		.duty_cycle11(50),
		.output_clock_frequency12("0 MHz"),
		.phase_shift12("0 ps"),
		.duty_cycle12(50),
		.output_clock_frequency13("0 MHz"),
		.phase_shift13("0 ps"),
		.duty_cycle13(50),
		.output_clock_frequency14("0 MHz"),
		.phase_shift14("0 ps"),
		.duty_cycle14(50),
		.output_clock_frequency15("0 MHz"),
		.phase_shift15("0 ps"),
		.duty_cycle15(50),
		.output_clock_frequency16("0 MHz"),
		.phase_shift16("0 ps"),
		.duty_cycle16(50),
		.output_clock_frequency17("0 MHz"),
		.phase_shift17("0 ps"),
		.duty_cycle17(50),
		.pll_type("General"),
		.pll_subtype("General")
	) altera_pll_i (
		.rst	(rst),
		.outclk	({outclk_0}),
		.locked	(locked),
		.fboutclk	( ),
		.fbclk	(1'b0),
		.refclk	(refclk)
	);
endmodule
module  pll_0002(

	// interface 'refclk'
	input wire refclk,

	// interface 'reset'
	input wire rst,

	// interface 'outclk0'
	output wire outclk_0,

	// interface 'outclk1'
	output wire outclk_1,

	// interface 'locked'
	output wire locked
);

	altera_pll #(
		.fractional_vco_multiplier("true"),
		.reference_clock_frequency("50.0 MHz"),
		.operation_mode("direct"),
		.number_of_clocks(2),
		.output_clock_frequency0("85.909080 MHz"),
		.phase_shift0("0 ps"),
		.duty_cycle0(50),
		.output_clock_frequency1("10.738635 MHz"),
		.phase_shift1("0 ps"),
		.duty_cycle1(50),
		.output_clock_frequency2("0 MHz"),
		.phase_shift2("0 ps"),
		.duty_cycle2(50),
		.output_clock_frequency3("0 MHz"),
		.phase_shift3("0 ps"),
		.duty_cycle3(50),
		.output_clock_frequency4("0 MHz"),
		.phase_shift4("0 ps"),
		.duty_cycle4(50),
		.output_clock_frequency5("0 MHz"),
		.phase_shift5("0 ps"),
		.duty_cycle5(50),
		.output_clock_frequency6("0 MHz"),
		.phase_shift6("0 ps"),
		.duty_cycle6(50),
		.output_clock_frequency7("0 MHz"),
		.phase_shift7("0 ps"),
		.duty_cycle7(50),
		.output_clock_frequency8("0 MHz"),
		.phase_shift8("0 ps"),
		.duty_cycle8(50),
		.output_clock_frequency9("0 MHz"),
		.phase_shift9("0 ps"),
		.duty_cycle9(50),
		.output_clock_frequency10("0 MHz"),
		.phase_shift10("0 ps"),
		.duty_cycle10(50),
		.output_clock_frequency11("0 MHz"),
		.phase_shift11("0 ps"),
		.duty_cycle11(50),
		.output_clock_frequency12("0 MHz"),
		.phase_shift12("0 ps"),
		.duty_cycle12(50),
		.output_clock_frequency13("0 MHz"),
		.phase_shift13("0 ps"),
		.duty_cycle13(50),
		.output_clock_frequency14("0 MHz"),
		.phase_shift14("0 ps"),
		.duty_cycle14(50),
		.output_clock_frequency15("0 MHz"),
		.phase_shift15("0 ps"),
		.duty_cycle15(50),
		.output_clock_frequency16("0 MHz"),
		.phase_shift16("0 ps"),
		.duty_cycle16(50),
		.output_clock_frequency17("0 MHz"),
		.phase_shift17("0 ps"),
		.duty_cycle17(50),
		.pll_type("General"),
		.pll_subtype("General")
	) altera_pll_i (
		.rst	(rst),
		.outclk	({outclk_1, outclk_0}),
		.locked	(locked),
		.fboutclk	( ),
		.fbclk	(1'b0),
		.refclk	(refclk)
	);
endmodule
module mycore
(
	input         clk,
	input         reset,
	
	input         pal,
	input         scandouble,

	output reg    ce_pix,

	output reg    HBlank,
	output reg    HSync,
	output reg    VBlank,
	output reg    VSync,

	output  [7:0] video
);

reg   [9:0] hc;
reg   [9:0] vc;
reg   [9:0] vvc;
reg  [63:0] rnd_reg;

wire  [5:0] rnd_c = {rnd_reg[0],rnd_reg[1],rnd_reg[2],rnd_reg[2],rnd_reg[2],rnd_reg[2]};
wire [63:0] rnd;

lfsr random(rnd);

always @(posedge clk) begin
	if(scandouble) ce_pix <= 1;
		else ce_pix <= ~ce_pix;

	if(reset) begin
		hc <= 0;
		vc <= 0;
	end
	else if(ce_pix) begin
		if(hc == 637) begin
			hc <= 0;
			if(vc == (pal ? (scandouble ? 623 : 311) : (scandouble ? 523 : 261))) begin 
				vc <= 0;
				vvc <= vvc + 9'd6;
			end else begin
				vc <= vc + 1'd1;
			end
		end else begin
			hc <= hc + 1'd1;
		end

		rnd_reg <= rnd;
	end
end

always @(posedge clk) begin
	if (hc == 529) HBlank <= 1;
		else if (hc == 0) HBlank <= 0;

	if (hc == 544) begin
		HSync <= 1;

		if(pal) begin
			if(vc == (scandouble ? 609 : 304)) VSync <= 1;
				else if (vc == (scandouble ? 617 : 308)) VSync <= 0;

			if(vc == (scandouble ? 601 : 300)) VBlank <= 1;
				else if (vc == 0) VBlank <= 0;
		end
		else begin
			if(vc == (scandouble ? 490 : 245)) VSync <= 1;
				else if (vc == (scandouble ? 496 : 248)) VSync <= 0;

			if(vc == (scandouble ? 480 : 240)) VBlank <= 1;
				else if (vc == 0) VBlank <= 0;
		end
	end
	
	if (hc == 590) HSync <= 0;
end

reg  [7:0] cos_out;
wire [5:0] cos_g = cos_out[7:3]+6'd32;
cos cos(vvc + {vc>>scandouble, 2'b00}, cos_out);

assign video = (cos_g >= rnd_c) ? {cos_g - rnd_c, 2'b00} : 8'd0;

endmodule
module  pll_0002(

	// interface 'refclk'
	input wire refclk,

	// interface 'reset'
	input wire rst,

	// interface 'outclk0'
	output wire outclk_0,

	// interface 'locked'
	output wire locked
);

	altera_pll #(
		.fractional_vco_multiplier("false"),
		.reference_clock_frequency("50.0 MHz"),
		.operation_mode("direct"),
		.number_of_clocks(1),
		.output_clock_frequency0("20.000000 MHz"),
		.phase_shift0("0 ps"),
		.duty_cycle0(50),
		.output_clock_frequency1("0 MHz"),
		.phase_shift1("0 ps"),
		.duty_cycle1(50),
		.output_clock_frequency2("0 MHz"),
		.phase_shift2("0 ps"),
		.duty_cycle2(50),
		.output_clock_frequency3("0 MHz"),
		.phase_shift3("0 ps"),
		.duty_cycle3(50),
		.output_clock_frequency4("0 MHz"),
		.phase_shift4("0 ps"),
		.duty_cycle4(50),
		.output_clock_frequency5("0 MHz"),
		.phase_shift5("0 ps"),
		.duty_cycle5(50),
		.output_clock_frequency6("0 MHz"),
		.phase_shift6("0 ps"),
		.duty_cycle6(50),
		.output_clock_frequency7("0 MHz"),
		.phase_shift7("0 ps"),
		.duty_cycle7(50),
		.output_clock_frequency8("0 MHz"),
		.phase_shift8("0 ps"),
		.duty_cycle8(50),
		.output_clock_frequency9("0 MHz"),
		.phase_shift9("0 ps"),
		.duty_cycle9(50),
		.output_clock_frequency10("0 MHz"),
		.phase_shift10("0 ps"),
		.duty_cycle10(50),
		.output_clock_frequency11("0 MHz"),
		.phase_shift11("0 ps"),
		.duty_cycle11(50),
		.output_clock_frequency12("0 MHz"),
		.phase_shift12("0 ps"),
		.duty_cycle12(50),
		.output_clock_frequency13("0 MHz"),
		.phase_shift13("0 ps"),
		.duty_cycle13(50),
		.output_clock_frequency14("0 MHz"),
		.phase_shift14("0 ps"),
		.duty_cycle14(50),
		.output_clock_frequency15("0 MHz"),
		.phase_shift15("0 ps"),
		.duty_cycle15(50),
		.output_clock_frequency16("0 MHz"),
		.phase_shift16("0 ps"),
		.duty_cycle16(50),
		.output_clock_frequency17("0 MHz"),
		.phase_shift17("0 ps"),
		.duty_cycle17(50),
		.pll_type("General"),
		.pll_subtype("General")
	) altera_pll_i (
		.rst	(rst),
		.outclk	({outclk_0}),
		.locked	(locked),
		.fboutclk	( ),
		.fbclk	(1'b0),
		.refclk	(refclk)
	);
endmodule
module fraction_table (clk, rst, index, fraction);
input clk;
input rst;
input [5:0] index;
output reg[15:0] fraction;

always @ (posedge clk)
begin 
  if (rst)
    fraction <= 16'hFFFF;
  else
    begin
      case (index)
        6'd0:  fraction <= 16'd8192;
        6'd1:  fraction <= 16'd4096;
        6'd2:  fraction <= 16'd2730;
        6'd3:  fraction <= 16'd2048;
        6'd4:  fraction <= 16'd1638;
        6'd5:  fraction <= 16'd1365;
        6'd6:  fraction <= 16'd1170;
        6'd7:  fraction <= 16'd1024;
        6'd8:  fraction <= 16'd910;
        6'd9:  fraction <= 16'd819;
        6'd10:  fraction <= 16'd744;
        6'd11:  fraction <= 16'd682;
        6'd12:  fraction <= 16'd630;
        6'd13:  fraction <= 16'd585;
        6'd14:  fraction <= 16'd546;
        6'd15:  fraction <= 16'd512;
        6'd16:  fraction <= 16'd481;
        6'd17:  fraction <= 16'd455;
        6'd18:  fraction <= 16'd431;
        6'd19:  fraction <= 16'd409;
        6'd20:  fraction <= 16'd390;
        6'd21:  fraction <= 16'd372;
        6'd22:  fraction <= 16'd356;
        6'd23:  fraction <= 16'd341;
        6'd24:  fraction <= 16'd327;
        6'd25:  fraction <= 16'd315;
        6'd26:  fraction <= 16'd303;
        6'd27:  fraction <= 16'd292;
        6'd28:  fraction <= 16'd282;
        6'd29:  fraction <= 16'd273;
        6'd30:  fraction <= 16'd264;
        6'd31:  fraction <= 16'd256;
        6'd32:  fraction <= 16'd248;
        6'd33:  fraction <= 16'd240;
        6'd34:  fraction <= 16'd234;
        6'd35:  fraction <= 16'd227;
        6'd36:  fraction <= 16'd221;
        6'd37:  fraction <= 16'd215;
        6'd38:  fraction <= 16'd210;
        6'd39:  fraction <= 16'd204;
        6'd40:  fraction <= 16'd199;
        6'd41:  fraction <= 16'd195;
        6'd42:  fraction <= 16'd190;
        6'd43:  fraction <= 16'd186;
        6'd44:  fraction <= 16'd182;
        6'd45:  fraction <= 16'd178;
        6'd46:  fraction <= 16'd174;
        6'd47:  fraction <= 16'd170;
        6'd48:  fraction <= 16'd167;
        6'd49:  fraction <= 16'd163;
        6'd50:  fraction <= 16'd160;
        6'd51:  fraction <= 16'd157;
        6'd52:  fraction <= 16'd154;
        6'd53:  fraction <= 16'd151;
        6'd54:  fraction <= 16'd148;
        6'd55:  fraction <= 16'd146;
        6'd56:  fraction <= 16'd143;
        6'd57:  fraction <= 16'd141;
        6'd58:  fraction <= 16'd138;
        6'd59:  fraction <= 16'd136;
        6'd60:  fraction <= 16'd134;
        6'd61:  fraction <= 16'd132;
        6'd62:  fraction <= 16'd130;
        6'd63:  fraction <= 16'd128;
      endcase
    end
  end
endmodule
module multiplier(
	clk,
	d_i,
	w_i,
	m_o
	);
parameter C_WIDTH = 2; // data channel, set to 2 when using 8 bit 
parameter D_WIDTH = 8;
parameter W_WIDTH = 16;
parameter M_WIDTH = 32;
/* W_WIDTH should be 1/2/8/16 */
input clk;
input [D_WIDTH-1:0] d_i;
input [W_WIDTH-1:0] w_i;
output wire [M_WIDTH-1:0] m_o;

reg  [M_WIDTH-1:0] m_o_reg;
wire  [M_WIDTH-1:0] m_o_tmp;

wire [23:0] w_i_tmp;

assign w_i_tmp = {{w_i[15:8] + {8{w_i[7]}}},{8{w_i[7]}}, w_i[7:0]};

generate 
case (W_WIDTH/C_WIDTH)
	1: 	always @(posedge clk)
		begin
			m_o_reg <= w_i[0]?(~d_i[D_WIDTH-1:0]+1):D_WIDTH[D_WIDTH-1:0];
		end
	2:  always @ (posedge clk)
        begin
			m_o_reg <= w_i[1]?(~d_i[D_WIDTH-1:0]+1):(w_i[0]?d_i[D_WIDTH-1:0]:{D_WIDTH{1'b0}});
        end
	8:  if (D_WIDTH == 8) begin
			mul24x8_signed u_mul24x8_signed (
			.CLK(clk),
			.A(w_i_tmp),
			.B(d_i[7:0]),
			.P(m_o_tmp) // output
			);
			assign m_o[15:0] = m_o_tmp[15:0];
			assign m_o[31:16] = m_o_tmp[31:16]-{16{m_o_tmp[15]}};
			end
		else 
			mul16x16_signed u_mul16x16_signed (
			.CLK(clk),
			.A(w_i[15:0]),
			.B(d_i[15:0]),
			.P(m_o) // output
			);
	default: mul16x16_signed u_mul16x16_signed (
			.CLK(clk),
			.A(w_i[15:0]),
			.B(d_i[15:0]),
			.P(m_o) // output
			);
endcase
    if (W_WIDTH < 3) begin: gen_mo
        assign m_o = m_o_reg;
    end
endgenerate

endmodule
module busnto512(
  clk,
  rst,
  blob_din,
  blob_din_rdy,
  blob_din_en,
  blob_din_eop,
  blob_dout,
  blob_dout_rdy,
  blob_dout_en,
  blob_dout_eop
);

parameter IN_WIDTH  = 32 ;
parameter OUT_WIDTH = 512;
parameter COUNT     = 4  ;

//========================================
//input/output  declare
//========================================
input                                 clk;
input                                 rst;
input      [IN_WIDTH-1:0]             blob_din;
output                                blob_din_rdy;
input                                 blob_din_en;
input                                 blob_din_eop;
output     [OUT_WIDTH-1:0]            blob_dout;
input                                 blob_dout_rdy;
output                                blob_dout_en;
output                                blob_dout_eop;

reg auto_pad;
reg [COUNT-1:0] phase;

always @ (posedge clk)
begin
  if(rst)
    auto_pad <= 1'b0;
  else if(&phase)
    auto_pad <= 1'b0;
  else if(blob_din_en & blob_din_eop)
    auto_pad <= 1'b1;
  else
    auto_pad <= auto_pad;
end

always @ (posedge clk)
begin
  if(rst)
    phase <= 0;
  else if(blob_din_en | auto_pad)
	phase <= phase + 1'b1;
  else
    phase <= phase;
end

reg  [OUT_WIDTH-1:0]  blob_dout_tmp;
always @ (posedge clk)
begin
  if(rst)
    blob_dout_tmp <= 0;
  else if(blob_din_en | auto_pad)
    blob_dout_tmp <= {blob_din,blob_dout_tmp[OUT_WIDTH-1:IN_WIDTH]};
  else
    blob_dout_tmp <= blob_dout_tmp;
end

assign blob_din_rdy  = blob_dout_rdy & (~auto_pad);
assign blob_dout_en  = (blob_din_en | auto_pad) & (&phase);
assign blob_dout_eop =(blob_din_eop | auto_pad) & (&phase);
assign blob_dout = (blob_din_en | auto_pad) ? {blob_din,blob_dout_tmp[OUT_WIDTH-1:IN_WIDTH]} : 0; 

endmodule
module addr3(
	clk,
	rst,
	d0_i,
	d1_i,
	d2_i,
	d_o
	);
parameter IN_WIDTH = 32;

input clk;
input rst;
input wire [IN_WIDTH-1:0] d0_i;
input wire [IN_WIDTH-1:0] d1_i;
input wire [IN_WIDTH-1:0] d2_i;
output reg [IN_WIDTH:0] d_o;

always @(posedge clk)
begin
	if (rst)
		d_o <= 0;
	else
		d_o <= {{1{d0_i[IN_WIDTH-1]}}, d0_i} + {{1{d1_i[IN_WIDTH-1]}}, d1_i} + {{1{d2_i[IN_WIDTH-1]}}, d2_i};
end
endmodule
module addr2(
	clk,
	rst,
	d0_i,
	d1_i,
	d_o
	);
parameter IN_WIDTH = 32;

input clk;
input rst;
input wire [IN_WIDTH-1:0] d0_i;
input wire [IN_WIDTH-1:0] d1_i;
output reg [IN_WIDTH:0] d_o;

always @(posedge clk)
begin
	if (rst)
		d_o <= 0;
	else
		d_o <= {{1{d0_i[IN_WIDTH-1]}}, d0_i} + {{1{d1_i[IN_WIDTH-1]}}, d1_i};
end
endmodule
module addr4(
	clk,
	rst,
	d0_i,
	d1_i,
	d2_i,
	d3_i,
	d_o
	);
parameter IN_WIDTH = 32;

input clk;
input rst;
input wire [IN_WIDTH-1:0] d0_i;
input wire [IN_WIDTH-1:0] d1_i;
input wire [IN_WIDTH-1:0] d2_i;
input wire [IN_WIDTH-1:0] d3_i;
output reg [IN_WIDTH+1:0] d_o;

always @(posedge clk)
begin
	if (rst)
		d_o <= 0;
	else
		d_o <= {{2{d0_i[IN_WIDTH-1]}}, d0_i} + {{2{d1_i[IN_WIDTH-1]}}, d1_i} + {{2{d2_i[IN_WIDTH-1]}}, d2_i} + {{2{d3_i[IN_WIDTH-1]}}, d3_i};
end
endmodule
module vector_max(
        clk,
        rst,
        op_din_en,
        op_din_eop,
        op_din,
        op_dout
);

//========================================
//parameter define                        
//========================================
parameter RELU = 0;
parameter DIN_W = 16;
parameter Q = 8;

//========================================
//input/output  declare
//========================================
input clk;
input rst;
input op_din_en;
input op_din_eop;
input signed [DIN_W-1:0] op_din;
output signed [DIN_W-1:0] op_dout; 
 
//========================================
//delay op_din_eop 1 clock
//========================================
reg op_din_eop_d1;
always @ (posedge clk)
begin
  if(rst)
    op_din_eop_d1 <= 1'b0;
  else
    op_din_eop_d1 <= op_din_eop;
end
//========================================
//select max value with signal
//========================================
reg signed [DIN_W-1:0] op_dout_tmp; 
always @ (posedge clk)
begin
  if(rst)
    op_dout_tmp <= {DIN_W{1'b0}};
  else if ((op_din_eop_d1 == 1'b1) && (op_din_en == 1'b1))
    op_dout_tmp <= op_din;
  else if ((op_din_eop_d1 == 1'b1) && (op_din_en == 1'b0))
    op_dout_tmp <= {1'b1, {(DIN_W-1){1'b0}}};
  else if ((op_din_eop_d1 == 1'b0) && (op_din_en == 1'b1))
    op_dout_tmp <= op_dout_tmp > op_din ? op_dout_tmp : op_din;
  else  
    op_dout_tmp <= op_dout_tmp;	
end

//========================================
//non-linearization deal
//========================================
assign op_dout = RELU ? (op_dout_tmp[DIN_W-1] ? 0 : op_dout_tmp) : op_dout_tmp;

endmodule
module vector_ave(
  clk,
  rst,
  op_din_en,
  op_din_eop,
  op_din,
  fraction,
  op_dout
 );
 
//========================================
//input/output  declare
//======================================== 
input clk;
input rst;
input op_din_en;
input op_din_eop;
input [15:0] op_din;
input [15:0] fraction;
output [15:0] op_dout; 

//========================================
//parameter define                        
//========================================
parameter RELU = 0;
//parameter FRACTION = 1000;
parameter Q = 8;

//========================================
//call mul IP core : op_din[15:0] * FRACTION
//========================================
wire [31:0] a1;
mul16_signed u_mul16_signed_1 (
  .CLK(clk),
  .A(op_din),
  .B(fraction),
  .P(a1)
);

//========================================
//delay op_din_en 1 clock
//========================================
reg op_din_en_d1;
always @ (posedge clk)
begin
  if(rst)
    op_din_en_d1 <= 1'b0;
  else
    op_din_en_d1 <= op_din_en;
end

//========================================
//delay op_din_eop 2 clock
//========================================
wire op_din_eop_d2;
delay #(2)u_delay_1(
  .clk(clk),
  .rst(rst),
  .in(op_din_eop),
  .out(op_din_eop_d2)
);

//========================================
//accumulation with signal
//========================================
reg [31:0] sum;
always @ (posedge clk)
begin
  if(rst)
    sum <= 32'b0;
  else if ((op_din_eop_d2 == 1) && (op_din_en_d1 == 1))
    sum <= a1;
  else if ((op_din_eop_d2 == 1) && (op_din_en_d1 == 0))
    sum <= 32'b0;
  else if ((op_din_eop_d2 == 0) && (op_din_en_d1 == 1))
    sum <= sum + a1;
  else  
    sum <= sum;	
end

wire [15:0] op_dout_tmp;
bit_trunc #(
  .WIDTH(32),
  .MSB(Q+15),
  .LSB(Q)
) 
u_bit_trunc_2(
  .din(sum),
  .dout(op_dout_tmp)
);

assign op_dout = RELU ? (op_dout_tmp[15] ? 0 : op_dout_tmp) : op_dout_tmp;

endmodule
module bit_trunc(
          din,
          dout
    );

//========================================
//parameter define                        
//========================================
	 parameter WIDTH = 16;
	 parameter MSB   = 15;
	 parameter LSB   = 0;
     parameter ROUND = 0;
                          
//========================================
//input/output  declare
//========================================
   input      [WIDTH -1:0]    din ;
   output reg [MSB : LSB]     dout;


//========================================
//code begin here
//========================================	 
	 
wire [WIDTH -1:0] din_tmp;	 
generate
  if (ROUND == 1 && LSB > 0) begin: round
    assign din_tmp = din[LSB-1] == 1'b1 ? din + {{(WIDTH-LSB-1){din[WIDTH-1]}},1'b1,{(LSB){1'b0}}} : din;
  end
  else begin
    assign din_tmp = din;
  end
endgenerate

always@( * )
  begin
    if(din_tmp[WIDTH-1] == 1'b0 && ((|din_tmp[WIDTH-1 : MSB])) == 1'b1) //overflow	 
      dout <= {1'b0, {(MSB - LSB){1'b1}}};
    else if(din_tmp[WIDTH-1] == 1'b1 && ((&din_tmp[WIDTH-1 : MSB])) == 1'b0) //underflow  
      dout <= {1'b1, {(MSB - LSB){1'b0}}};
    else //without flow
      dout <= din_tmp[MSB : LSB];
  end

endmodule
module delay(clk,rst,in,out);
input clk;
input rst;
input in;
output out;

parameter N = 2;

generate
	if (N == 0) begin : gen_delay_block
		assign out = in;
	end
	else if (N == 1) begin
(*mark_debug="true"*)reg				delay_line;

		always @ (posedge clk)
		begin
			delay_line 	<= in;
		end

		assign out = delay_line;
	end
	else begin
		genvar i;
(*mark_debug="true"*)reg		[N-1:0]		delay_line;

		always @ (posedge clk)
		begin
			delay_line [0]	<= in;
		end

		for (i=1; i < N; i=i+1) begin:gen_delay_line
			always @ (posedge clk)
			begin
				delay_line [i]	<= delay_line [i-1];
			end
		end

		assign	out = delay_line [N-1];
	end
endgenerate


endmodule
module passthrough(
  clk,
  rst,
  op_din_en,
  op_din_eop,
  op_din,
  op_dout
);

parameter Q = 8;
parameter RELU = 0;

input clk;
input rst;
input op_din_en;
input op_din_eop;
input [15:0] op_din;
output [15:0] op_dout;

assign op_dout = op_din;

endmodule
module bus512ton(
  clk,
  rst,
  blob_din,
  blob_din_rdy,
  blob_din_en,
  blob_din_eop,
  blob_dout,
  blob_dout_rdy,
  blob_dout_en,
  blob_dout_eop
);

parameter IN_WIDTH  = 512 ;
parameter OUT_WIDTH = 32;
parameter COUNT     = 4;
parameter N         = 320;

//========================================
//input/output  declare
//========================================
input                                 clk;
input                                 rst;
input      [IN_WIDTH-1:0]             blob_din;
output                                blob_din_rdy;
input                                 blob_din_en;
input                                 blob_din_eop;
output     [OUT_WIDTH-1:0]            blob_dout;
input                                 blob_dout_rdy;
output                                blob_dout_en;
output                                blob_dout_eop;

reg [COUNT-1:0] dout_cnt;
reg [31:0] dout_cnt_total;
always @ (posedge clk)
begin
  if(rst | (dout_cnt_total == N-1))
    dout_cnt <= 0;
  else if(blob_dout_en)
    dout_cnt <= dout_cnt + 1'b1;
  else
    dout_cnt <= dout_cnt;
end

always @ (posedge clk)
begin
  if(rst)
    dout_cnt_total <= 32'b0;
  else if(blob_dout_en)
  begin
    if(dout_cnt_total == N-1)
      dout_cnt_total <= 32'b0;
    else
      dout_cnt_total <= dout_cnt_total + 1'b1;
  end
  else
    dout_cnt_total <= dout_cnt_total;
end

reg last_blob_din;
always @ (posedge clk)
begin
  if (rst)
     last_blob_din <= 1'b0;
  else if (blob_din_en)
     last_blob_din <= blob_din_eop;
  else
     last_blob_din <= last_blob_din;
end

reg trunc_en;
always @ (posedge clk)
begin
  if(rst)
      trunc_en <= 1'b0;
  else if(blob_din_eop)
      trunc_en <= 1'b0;
  else if(blob_dout_eop & (~last_blob_din)) 
      trunc_en <= 1'b1;
  else
      trunc_en <= trunc_en;
end

reg read_write_sel;
always @ (posedge clk)
begin
  if(rst)
    read_write_sel <= 1'b0;
  else if(blob_din_en & (~trunc_en))
    read_write_sel <= 1'b1;
  else if(blob_dout_en & ((&dout_cnt)|(dout_cnt_total == N-1)))
    read_write_sel <= 1'b0;
  else
    read_write_sel <= read_write_sel;
end

reg  [IN_WIDTH-1:0]  din_tmp;
always @ (posedge clk)
begin
  if(rst)
    din_tmp <= 0;
  else if(blob_din_en & (~trunc_en))
    din_tmp <= blob_din;
  else if(blob_dout_rdy)
    din_tmp <= (din_tmp >> OUT_WIDTH);
  else
    din_tmp <= din_tmp;
end

assign blob_dout = din_tmp[OUT_WIDTH-1:0];
assign blob_din_rdy = ~read_write_sel;
assign blob_dout_en = read_write_sel & blob_dout_rdy;
assign blob_dout_eop = blob_dout_en & (dout_cnt_total == N-1);

endmodule
module bn_bias_relu(
  clk,
  rst,
  acc_in,
  op_bias,
  op_dout
);

//========================================
//parameter define                        
//========================================
parameter RELU = 0;
parameter Q = 8;
parameter DIN_Q = 6;
parameter DOUT_DW = 16;
parameter DOUT_Q = 6;
parameter ACC_WIDTH = 40;
parameter BIAS_DW = 16;
parameter BN = 0;
parameter BN_SCALE_Q = 13;
parameter BN_BIAS_Q = 13;
parameter MID_Q = 13;

//========================================
//input/output  declare
//========================================
input clk;
input rst;
input [ACC_WIDTH-1: 0] acc_in;
input [BIAS_DW-1:0] op_bias;
output reg[DOUT_DW-1:0] op_dout;

//========================================
// BN or bias
//========================================
wire [DOUT_DW-1:0] op_dout_tmp;
generate
  //Without BN, use bias
  if (BN == 0) begin: gen_block_without_bn
    reg [ACC_WIDTH-1:0] op_acc;
    always @ (posedge clk)
    begin
      if(rst)
        op_acc <= {ACC_WIDTH{1'b0}};
      else
        op_acc <= acc_in + ({{(ACC_WIDTH-BIAS_DW){op_bias[BIAS_DW-1]}}, op_bias} << DIN_Q);  //bias with bw=BIAS_DW, Q=Q
    //acc_in with bw=ACC_WIDTH, Q=DIN_Q+Q(from weight)
    //op_acc with bw=ACC_WIDTH, Q=DIN_Q+Q
    end
    bit_trunc #(
      .ROUND(1),
      .WIDTH(ACC_WIDTH),
      .MSB(Q+DIN_Q-DOUT_Q+DOUT_DW-1),
      .LSB(Q+DIN_Q-DOUT_Q)
    )
    u0_bit_trunc(
      .din(op_acc),
      .dout(op_dout_tmp)
    );
  end
  // With BN enable
  else begin: gen_block_with_bn
    wire[15:0] acc_mid; //with Q=MID_Q
    //assign acc_mid = acc_in[Q+DIN_Q-MID_Q+15: Q+DIN_Q-MID_Q];
    bit_trunc #(
      .ROUND(0),
      .WIDTH(ACC_WIDTH),
      .MSB(Q+DIN_Q-MID_Q+15),
      .LSB(Q+DIN_Q-MID_Q)
    )
    u1_bit_trunc(
      .din(acc_in),
      .dout(acc_mid)
    );
    wire[15:0] bn_scale = op_bias[15:0];//with Q=BN_SCALE_Q
    reg[15:0] bn_bias_d1;
    always @ (posedge clk)
    begin
        bn_bias_d1 <= op_bias[31:16];
    end
    wire[31:0] acc_scaled;
    mul16_signed u_mul16_signed_bn (
      .CLK(clk),
      .A(acc_mid),
      .B(bn_scale),
      .P(acc_scaled) //with 32bit, Q=MID_Q+BN_SCALE_Q
    );
    reg[31:0] batch_out;
    always @(posedge clk)
    begin
      if (rst)
        batch_out <= 32'b0;
      else
        batch_out <= acc_scaled + ({{16{bn_bias_d1[15]}}, bn_bias_d1} << (MID_Q+BN_SCALE_Q-BN_BIAS_Q));
    end    
    bit_trunc #(
    //  .WIDTH(ACC_WIDTH),
      .ROUND(1),
      .WIDTH(32),
      .MSB(MID_Q+BN_SCALE_Q-DOUT_Q+DOUT_DW-1),
      .LSB(MID_Q+BN_SCALE_Q-DOUT_Q)
    )
    u2_bit_trunc(
      .din(batch_out),
      .dout(op_dout_tmp)
    );
  end
endgenerate

//========================================
//non-linearization deal
//========================================
always @(posedge clk)
begin
  if (rst)
    op_dout <= {DOUT_DW{1'b0}};
  else 
    op_dout <= RELU ? (op_dout_tmp[DOUT_DW-1] ? 0 : op_dout_tmp) : op_dout_tmp;
end
endmodule
module vect_muladd_tb();

parameter DIN_DW=8;
parameter DIN_Q=2;
parameter WW=8;
parameter WQ=8;
parameter CPF=32;
parameter DATA_CHANNEL = 2; // when using 8bit, set to 2
parameter DOUT_DW = 8; //bit-width of output 
parameter DOUT_Q=1;
parameter DIN_VECT=32/CPF;

reg clk,rst;
reg op_din_en;
reg [DIN_DW*CPF-1:0] op_din;
reg op_din_eop;
reg [WW*DATA_CHANNEL*CPF-1:0] op_weight;


wire  [DOUT_DW*DATA_CHANNEL-1:0] op_dout;

integer fpin,fpw;

initial begin
   clk = 0;
   #3;
   forever    clk = #2 ~clk;
end


initial begin
  rst = 0;
  op_din_en=0;
  op_din = 0;
  op_din_eop = 0;
  #199;
  rst = 1;
  #200;
  rst = 0;
  fpin=$fopen("/home/bjzhuc/muladdr/data/hexout/din.txt","r");
  fpw=$fopen("/home/bjzhuc/muladdr/data/hexout/weight.txt","r");
  
/*  while(!$feof(fpin))  // 写文件结束标志
   begin
   @(posedge clk) begin
     op_din_en = 1'b1;
     $fscanf(fpin,"%h",op_din);
   end
   #4;
   op_din_en = 1'b0;
*/

end

integer cnt;

always @(posedge clk)
begin
   if (rst) begin
      op_din <= 0;
      op_din_en <= 0;
      op_din_eop <= 1'b0;
      cnt <=0;
   end
   else if (!$feof(fpin)) begin 
      op_din_en <= 1'b1;
      $fscanf(fpin, "%h\n", op_din);
      cnt <= cnt+1;
      if (cnt == DIN_VECT-1)
        op_din_eop <= 1'b1;
      else
        op_din_eop <= 1'b0;
   end
   else begin
      op_din_en <= 0;
      op_din_eop <= 1'b0;
    //  $fclose(fpin);
   end
end  

always @(posedge clk)
begin
   if (rst)
      op_weight <= 0;
   else if (!$feof(fpw)) 
      $fscanf(fpw, "%h\n", op_weight);
   else
      $fclose(fpw);
end  

vector_muladd #(
 	.CPF(CPF),
 	.RELU(0),
 	.Q(WQ),
 	.DIN_Q(DIN_Q),
 	.DOUT_Q(DOUT_Q),
 	.ACC_WIDTH(40),
 	.BIAS_DW(4),
 	.BN(0),
 	.BN_SCALE_Q(13),
 	.BN_BIAS_Q(13),
 	.MID_Q(12),
 	.DIN_DW(DIN_DW),
 	.DOUT_DW(DOUT_DW), 
 	.WW(WW),
 	.DATA_CHANNEL(DATA_CHANNEL)) 
 	uut (
        .clk(clk),
        .rst(rst),
        .op_din_en(op_din_en),
        .op_din_eop(op_din_eop),
        .op_din(op_din),
        .op_weight(op_weight),
        .op_bias(0),
        .op_dout(op_dout)
    );

endmodule
module ddr3_dma_write
(
  clk,
  ddr_clk,
  rst,

  //ddr3 Interface
  init_calib_complete,
  app_addr,
  app_cmd,
  app_rdy,
  app_en,
  app_wdf_data,
  app_wdf_rdy,  
  app_wdf_wren,
  app_wdf_end,

  //dma Interface
  write_req,
  write_start_addr,
  write_length,
  write_done,

  din_rdy,
  din_en,
  din,
  din_eop
);

input                   clk;
input					ddr_clk;
input                   rst;

//ddr3 Interface
input                   init_calib_complete;
output     [29:0]		app_addr;
output     [2:0]		app_cmd;
input			        app_rdy;
output   		        app_en;
output     [511:0]      app_wdf_data;
input			        app_wdf_rdy;  
output			        app_wdf_wren;
output			        app_wdf_end;

//dma Interface
input                   write_req;
input  [26:0]           write_start_addr;
input  [26:0]           write_length;
output reg              write_done;

output                  din_rdy;
input                   din_en;
input  [511:0]          din;
input                   din_eop;


reg     [26:0]          write_left;
reg                     pre_done;
reg                     write_en;



reg     [29:0]			write_addr;

always @ (posedge clk)
begin
  write_addr [2:0]	<= 3'h0;

  if(write_req)
	write_addr [29:3] <= write_start_addr;
  else if (din_en)
	write_addr [29:3] <= write_addr [29:3] + 1;
end

// Assuming the write_length is always >= 2
always @ (posedge clk)
begin
  if(write_req)
	write_left  <= write_length;
  else if (din_en & write_en)
	write_left  <= write_left - 1;
end

always @ (posedge clk)
begin
  if (write_req)
    pre_done    <= 0;
  else if (din_en & (~|write_left [26:2]) & write_left [1] & (~write_left [0]))
    pre_done    <= 1;
end

always @ (posedge clk)
begin
  if (rst)
    write_en    <= 0;
  else if (write_req)
    write_en    <= 1;
  else if (din_en & (pre_done | din_eop))
    write_en    <= 0;
end

always @ (posedge clk)
  write_done    <= din_en & write_en & (pre_done | din_eop);


wire				ddr_write_fifo_wen;
wire				ddr_write_fifo_afull;

// There is no buffer here, so follow control happens outside
assign	ddr_write_fifo_wen	= din_en & write_en;
assign	din_rdy				= write_en & ~ddr_write_fifo_afull;


/*
SYNC_FIFO_WRAPPER # (9, 542, 480)	ddr_write_fifo
(
	.reset_i(rst),
	.clk_i(clk),
	.w_en_i(ddr_write_fifo_wen),
	.w_din_i({write_addr, din}),

	.r_en_i(ddr_write_fifo_rd),
	.r_dout_o({app_addr, app_wdf_data}),

	.full_o(),
	.afull_o(ddr_write_fifo_afull),
	.empty_o(ddr_write_fifo_empty)
);
*/

ddr_write_fifo	ddr_write_fifo
(
	.rst(rst),
	.wr_clk(clk),
	.wr_en(ddr_write_fifo_wen),
	.din({write_addr, din}),

	.rd_clk(ddr_clk),
	.rd_en(ddr_write_fifo_rd),
	.dout({app_addr, app_wdf_data}),

	.full(),
	.empty(ddr_write_fifo_empty),
	.prog_full(ddr_write_fifo_afull)
);


assign	ddr_write_fifo_rd	= app_wdf_rdy & app_rdy & ~(ddr_write_fifo_empty);
assign	app_wdf_wren		= ddr_write_fifo_rd;
assign	app_wdf_end			= ddr_write_fifo_rd;

assign	app_en				= ddr_write_fifo_rd;
assign	app_cmd				= 3'b0; //ddr write command.  

endmodule
module ddr3_dma_mux
(
  clk,
  rst,

  write_req,
  write_app_cmd,
  write_app_addr,
  write_app_en,

  read_req,
  read_app_cmd,
  read_app_addr,
  read_app_en, 

  app_cmd,
  app_addr,
  app_en
);

input               clk;
input               rst;

input               write_req;
input   [2:0]       write_app_cmd;
input   [29:0]      write_app_addr;
input               write_app_en;

input               read_req;
input   [2:0]       read_app_cmd;
input   [29:0]      read_app_addr;
input               read_app_en;

output  [2:0]       app_cmd;
output  [29:0]      app_addr;
output              app_en;


//  DDR read and write will not happen simultaneously
(*mark_debug = "true"*)reg                 sel;

always @ (posedge clk)
begin
  if(rst)
    sel <= 1'b1;
  else if (read_req)
    sel <= 1'b1;
  else if (write_req)
    sel <= 1'b0;
end

assign app_cmd  = sel ? read_app_cmd : write_app_cmd;
assign app_addr = sel ? read_app_addr : write_app_addr;
assign app_en   = sel ? read_app_en : write_app_en;




endmodule
module \$_ALDFF_PN_ (D, C, L, AD, Q);
input D, C, L, AD;
output reg Q;

wire RN, SN;
wire L_N;

\$_OR_ R_NAND ( .Y(RN), .A(L), .B(AD) );
\$_NOT_ NAND_NOT ( .A(L), .Y(L_N));
\$_NAND_ S_NAND ( .Y(SN), .A(L_N), .B(AD) );

\$_DFFSR_PNN_ SRFF (.C(C), 
    .S(SN), 
    .R(RN), 
    .D(D), 
    .Q(Q)
);

endmodule
module sky130_fd_io__top_xres4v2 ( TIE_WEAK_HI_H,  XRES_H_N, TIE_HI_ESD, TIE_LO_ESD,
    AMUXBUS_A, AMUXBUS_B, PAD, PAD_A_ESD_H, ENABLE_H, EN_VDDIO_SIG_H, INP_SEL_H, FILT_IN_H,
    DISABLE_PULLUP_H, PULLUP_H, ENABLE_VDDIO
    ,VCCD, VCCHIB, VDDA, VDDIO,VDDIO_Q, VSSA, VSSD, VSSIO, VSSIO_Q, VSWITCH
     );
    output XRES_H_N;
    inout AMUXBUS_A;
    inout AMUXBUS_B;
    inout PAD;
    input DISABLE_PULLUP_H;
    input ENABLE_H; 
    input EN_VDDIO_SIG_H; 
    input INP_SEL_H; 
    input FILT_IN_H;
    inout PULLUP_H;
    input ENABLE_VDDIO;
    input VCCD;
    input VCCHIB;
    input VDDA;
    input VDDIO;
    input VDDIO_Q;
    input VSSA;
    input VSSD;
    input VSSIO;
    input VSSIO_Q;
    input VSWITCH;
    inout PAD_A_ESD_H;
    output TIE_HI_ESD;
    output TIE_LO_ESD;
    inout TIE_WEAK_HI_H;
endmodule
module sky130_ef_sc_hd__decap_12(
    input VPWR,
    input VGND,
    input VPB,
    input VNB
  );

endmodule
module \$_MUX_ (
    output Y,
    input A,
    input B,
    input S
    );
  sky130_fd_sc_hd__mux2_2 _TECHMAP_MUX (
      .X(Y),
      .A0(A),
      .A1(B),
      .S(S)
  );
endmodule
module sky130_fd_sc_hd__tapvpwrvgnd_1 ();

endmodule
module spare_logic_block (
    `ifdef USE_POWER_PINS
        inout vccd,
        inout vssd,
    `endif

    output [26:0] spare_xz,	// Constant 0 outputs (and block inputs)
    output [3:0]  spare_xi,	// Inverter outputs
    output	  spare_xib,	// Big inverter output
    output [1:0]  spare_xna,	// NAND outputs
    output [1:0]  spare_xno,	// NOR outputs
    output [1:0]  spare_xmx,	// Mux outputs
    output [1:0]  spare_xfq,	// Flop noninverted output
    output [1:0]  spare_xfqn 	// Flop inverted output
);

    wire [3:0] spare_logic_nc;

    wire [26:0] spare_logic1;
    wire [26:0] spare_logic0;

    // Rename the logic0 outputs at the block pins.
    assign spare_xz = spare_logic0;

    sky130_fd_sc_hd__conb_1 spare_logic_const [26:0] (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
	`endif
            .HI(spare_logic1),
            .LO(spare_logic0)
    );

    sky130_fd_sc_hd__inv_2 spare_logic_inv [3:0] (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
	`endif
            .Y(spare_xi),
            .A(spare_logic0[3:0])
    );

    sky130_fd_sc_hd__inv_8 spare_logic_biginv (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
	`endif
            .Y(spare_xib),
            .A(spare_logic0[4])
    );

    sky130_fd_sc_hd__nand2_2 spare_logic_nand [1:0] (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
	`endif
            .Y(spare_xna),
            .A(spare_logic0[6:5]),
            .B(spare_logic0[8:7])
    );

    sky130_fd_sc_hd__nor2_2 spare_logic_nor [1:0] (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
	`endif
            .Y(spare_xno),
            .A(spare_logic0[10:9]),
            .B(spare_logic0[12:11])
    );

    sky130_fd_sc_hd__mux2_2 spare_logic_mux [1:0] (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
	`endif
            .X(spare_xmx),
            .A0(spare_logic0[14:13]),
            .A1(spare_logic0[16:15]),
            .S(spare_logic0[18:17])
    );

    sky130_fd_sc_hd__dfbbp_1 spare_logic_flop [1:0] (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
	`endif
            .Q(spare_xfq),
            .Q_N(spare_xfqn),
            .D(spare_logic0[20:19]),
            .CLK(spare_logic0[22:21]),
            .SET_B(spare_logic0[24:23]),
            .RESET_B(spare_logic0[26:25])
    );

    sky130_fd_sc_hd__tapvpwrvgnd_1 spare_logic_tap [1:0] (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd)
	`endif
    );

    sky130_fd_sc_hd__diode_2 spare_logic_diode [3:0] (
	`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
	`endif
	    .DIODE(spare_logic_nc)
    );
 
endmodule
module constant_block (
    `ifdef USE_POWER_PINS
         inout vccd,
         inout vssd,
    `endif

    output	 one,
    output	 zero
);

    wire	one_unbuf;
    wire	zero_unbuf;

    sky130_fd_sc_hd__conb_1 const_source (
`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
`endif
            .HI(one_unbuf),
            .LO(zero_unbuf)
    );

    /* Buffer the constant outputs (could be synthesized) */
    /* NOTE:  Constant cell HI, LO outputs are connected to power	*/
    /* rails through an approximately 120 ohm resistor, which is not	*/
    /* enough to drive inputs in the I/O cells while ensuring ESD	*/
    /* requirements, without buffering.					*/

    sky130_fd_sc_hd__buf_16 const_one_buf (
`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
`endif
            .A(one_unbuf),
            .X(one)
    );

    sky130_fd_sc_hd__buf_16 const_zero_buf (
`ifdef USE_POWER_PINS
            .VPWR(vccd),
            .VGND(vssd),
            .VPB(vccd),
            .VNB(vssd),
`endif
            .A(zero_unbuf),
            .X(zero)
    );

endmodule
module user_id_programming #(
    parameter USER_PROJECT_ID = 32'h0
) (
`ifdef USE_POWER_PINS
    inout VPWR,
    inout VGND,
`endif
    output [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
module user_project_la_example (
    // Logic Analyzer Signals
    input  [127:0] la_data_in,
    output [127:0] la_data_out,
    input  [127:0] la_oenb
);
    // LA
    assign la_data_out[63:32]  =  la_oenb[31:0]   ?  32'hz: la_data_in[31:0]   ; // assign la0 to la1 if la0 output enable
    assign la_data_out[31:0]   =  la_oenb[63:32]  ?  32'hz: la_data_in[63:32]   ; // assign la1 to la0 if la1 output enable
    assign la_data_out[127:96] =  la_oenb[95:64]  ?  32'hz: la_data_in[95:64]   ; // assign la2 to la3 if la2 output enable
    assign la_data_out[95:64]  =  la_oenb[127:96] ?  32'hz: la_data_in[127:96]  ; // assign la3 to la2 if la3 output enable
    // // LA
    // assign la_data_out[63:32]  =  la_oenb[31:0]   ?  la_data_in[31:0]   : 32'hz ; // assign la0 to la1 if la0 output enable
    // assign la_data_out[31:0]   =  la_oenb[63:32]  ?  la_data_in[63:32]  : 32'hz ; // assign la1 to la0 if la1 output enable
    // assign la_data_out[127:96] =  la_oenb[95:64]  ?  la_data_in[95:64]  : 32'hz ; // assign la2 to la3 if la2 output enable
    // assign la_data_out[95:64]  =  la_oenb[127:96] ?  la_data_in[127:96] : 32'hz ; // assign la3 to la2 if la3 output enable
   

endmodule
module gpio_defaults_block #(
    // Parameterized initial startup state of the pad.  The default
    // parameters if unspecified is for the pad to be a user input
    // with no pull-up or pull-down, so that it is disconnected
    // from the outside world.  See defs.h for configuration word
    // definitions.
    parameter GPIO_CONFIG_INIT = 13'h0402
) (
`ifdef USE_POWER_PINS
    inout VPWR,
    inout VGND,
`endif
    output [12:0] gpio_defaults
);
    wire [12:0] gpio_defaults_high;
    wire [12:0] gpio_defaults_low;

    // For the mask revision input, use an array of digital constant logic cells

    sky130_fd_sc_hd__conb_1 gpio_default_value [12:0] (
`ifdef USE_POWER_PINS
            .VPWR(VPWR),
            .VPB(VPWR),
            .VNB(VGND),
            .VGND(VGND),
`endif
            .HI(gpio_defaults_high),
            .LO(gpio_defaults_low)
    );

    genvar i;
    generate
        for (i = 0; i < 13; i = i+1) begin
    	    assign gpio_defaults[i] = (GPIO_CONFIG_INIT & (13'h0001 << i)) ?
			gpio_defaults_high[i] : gpio_defaults_low[i];
	end
    endgenerate

endmodule
module mprj_logic_high (
`ifdef USE_POWER_PINS
    inout	   vccd1,
    inout	   vssd1,
`endif
    output [462:0] HI
);
sky130_fd_sc_hd__conb_1 insts [462:0] (
`ifdef USE_POWER_PINS
                .VPWR(vccd1),
                .VGND(vssd1),
                .VPB(vccd1),
                .VNB(vssd1),
`endif
                .HI(HI),
                .LO()
        );
endmodule
module caravel_clocking(
`ifdef USE_POWER_PINS
    input VPWR,
    input VGND,
`endif
    input porb,		// Master (negative sense) reset from power-on-reset
    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;

    wire resetb_async;

    assign pll_clk_sel = ~ext_clk_sel;

    assign resetb_async = porb & resetb & (!ext_reset);
    // 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_async) begin
	if (resetb_async == 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_async)
    ); 

    // Secondary PLL clock divider for user space access

    clock_div #(
	.SIZE(3)
    ) divider2 (
	.in(pll_clk90),
	.out(pll_clk90_divided),
	.N(sel2),
	.resetb(resetb_async)
    ); 


    // 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 @(negedge core_clk or negedge resetb_async) begin
        if (resetb_async == 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];

endmodule
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 [1:0]   clockp_buffer_in;	// Input wires to clockp buffers
    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;

    (* keep *)
    ring_osc2x13 ringosc (
        .reset(ireset),
        .trim(itrim),
        .clockp(clockp_buffer_in)
    );

    digital_pll_controller pll_control (
        .reset(creset),
        .clock(clockp_buffer_in[0]),
        .osc(osc),
        .div(div),
        .trim(otrim)
    );

    (* keep *)
    sky130_fd_sc_hd__clkbuf_16 clockp_buffer_0 (
`ifdef USE_POWER_PINS
        .VPWR(VPWR),
        .VGND(VGND),
        .VPB(VPWR),
        .VNB(VGND),
`endif
        .A(clockp_buffer_in[0]),
        .X(clockp[0])
    );

    (* keep *)
    sky130_fd_sc_hd__clkbuf_16 clockp_buffer_1 (
`ifdef USE_POWER_PINS
        .VPWR(VPWR),
        .VGND(VGND),
        .VPB(VPWR),
        .VNB(VGND),
`endif
        .A(clockp_buffer_in[1]),
        .X(clockp[1])
    );

endmodule
module buff_flash_clkrst (
	`ifdef USE_POWER_PINS
		inout VPWR,
		inout VGND,
	`endif
	input[11:0] in_n, 
	input[2:0] in_s, 
	output[11:0] out_s, 
	output[2:0] out_n);

	sky130_fd_sc_hd__clkbuf_8 BUF[14:0] (
		`ifdef USE_POWER_PINS
			.VGND(VGND),
			.VNB(VGND),
			.VPB(VPWR),
			.VPWR(VPWR),
		`endif
		.A({in_n, in_s}), 
		.X({out_s, out_n})); 

endmodule