dakies/OSS_Verilog huggingface dataset:
module nor_2(y, a, b, rst, clk);
    parameter delay = 9;
    parameter iv = 1'b0;
    input wire a, b, rst, clk;

`ifdef TARGET_FPGA
    output reg y = iv;
    reg next_val = iv;
    reg prev_val = iv;
    wire result;
    
    assign result = ~(a|b);

    always @(posedge clk)
    begin
        prev_val = y;
        y = next_val;
    end

    always @(negedge clk)
    begin
        next_val = ((result == prev_val) && (y == iv)) ? iv : result;
    end
`else
    output wire y;
    assign #delay y = (rst) ? iv : ~(a|b);
`endif
endmodule
module U74HC244(oe1_n, a11, y24, a12, y23, a13, y22, a14, y21, gnd, a21, y14, a22, y13, a23, y12, a24, y11, oe2_n, vcc, rst, clk);
    localparam delay = 18;
    input wire vcc, gnd, rst, clk;
    input wire a11, a12, a13, a14, a21, a22, a23, a24;
    output wire y11, y12, y13, y14, y21, y22, y23, y24;
    input wire oe1_n, oe2_n;

    tri_buf #(delay) A(y11, a11, oe1_n);
    tri_buf #(delay) B(y12, a12, oe1_n);
    tri_buf #(delay) C(y13, a13, oe1_n);
    tri_buf #(delay) D(y14, a14, oe1_n);
    tri_buf #(delay) E(y21, a21, oe2_n);
    tri_buf #(delay) F(y22, a22, oe2_n);
    tri_buf #(delay) G(y23, a23, oe2_n);
    tri_buf #(delay) H(y24, a24, oe2_n);
endmodule
module U74LVC07(a1, y1, a2, y2, a3, y3, gnd, y4, a4, y5, a5, y6, a6, vcc, rst, clk);
    localparam delay = 2;
    localparam od_value = 1'b1;
    input wire vcc, gnd, rst, clk;
    input wire a1, a2, a3, a4, a5, a6;
    output wire y1, y2, y3, y4, y5, y6;

    od_buf #(delay, od_value) A(y1, a1);
    od_buf #(delay, od_value) B(y2, a2);
    od_buf #(delay, od_value) C(y3, a3);
    od_buf #(delay, od_value) D(y4, a4);
    od_buf #(delay, od_value) E(y5, a5);
    od_buf #(delay, od_value) F(y6, a6);
endmodule
module tri_buf(y, a, oe_n);
    parameter delay = 13;
    input wire a;
    input wire oe_n;
    output wire y;

`ifdef TARGET_FPGA
    assign y = (oe_n == 1'b0) ? a : 1'b0;
`else
    assign #delay y = (oe_n == 1'b0) ? a : 1'bZ;
`endif
endmodule
module U74HC02(y1, a1, b1, y2, a2, b2, gnd, a3, b3, y3, a4, b4, y4, vcc, rst, clk);
    parameter ic1 = 1'b0;
    parameter ic2 = 1'b0;
    parameter ic3 = 1'b0;
    parameter ic4 = 1'b0;
    localparam delay = 9;
    input wire vcc, gnd, rst, clk;
    input wire a1, b1, a2, b2, a3, b3, a4, b4;
    output wire y1, y2, y3, y4;

    // Treat loss of power like a reset hold
    wire vrst;
    assign vrst = (rst || !vcc);

    nor_2 #(delay, ic1) A(y1, a1, b1, vrst, clk);
    nor_2 #(delay, ic2) B(y2, a2, b2, vrst, clk);
    nor_2 #(delay, ic3) C(y3, a3, b3, vrst, clk);
    nor_2 #(delay, ic4) D(y4, a4, b4, vrst, clk);
endmodule
module U74HC27(a1, b1, a2, b2, c2, y2, gnd, y3, a3, b3, c3, y1, c1, vcc, rst, clk);
    parameter ic1 = 1'b0;
    parameter ic2 = 1'b0;
    parameter ic3 = 1'b0;
    localparam delay = 9;
    input wire vcc, gnd, rst, clk;
    input wire a1, b1, c1, a2, b2, c2, a3, b3, c3;
    output wire y1, y2, y3;

    // Treat loss of power like a reset hold
    wire vrst;
    assign vrst = (rst || !vcc);

    nor_3 #(delay, ic1) A(y1, a1, b1, c1, vrst, clk);
    nor_3 #(delay, ic2) B(y2, a2, b2, c2, vrst, clk);
    nor_3 #(delay, ic3) C(y3, a3, b3, c3, vrst, clk);
endmodule
module od_buf(y, a);
    parameter delay = 2;
    parameter od_value = 1'b1;
    input wire a;
    output wire y;

`ifdef TARGET_FPGA
    assign y = (od_value == 1'b1) ? a : ~a;
`else
    assign #delay y = (a == od_value) ? 1'bZ : 1'b0;
`endif
endmodule
module U74LVC06(a1, y1, a2, y2, a3, y3, gnd, y4, a4, y5, a5, y6, a6, vcc, rst, clk);
    localparam delay = 2;
    localparam od_value = 1'b0;
    input wire vcc, gnd, rst, clk;
    input wire a1, a2, a3, a4, a5, a6;
    output wire y1, y2, y3, y4, y5, y6;

    od_buf #(delay, od_value) A(y1, a1);
    od_buf #(delay, od_value) B(y2, a2);
    od_buf #(delay, od_value) C(y3, a3);
    od_buf #(delay, od_value) D(y4, a4);
    od_buf #(delay, od_value) E(y5, a5);
    od_buf #(delay, od_value) F(y6, a6);
endmodule
module U74HC04(a1, y1, a2, y2, a3, y3, gnd, y4, a4, y5, a5, y6, a6, vcc, rst, clk);
    parameter ic1 = 1'b0;
    parameter ic2 = 1'b0;
    parameter ic3 = 1'b0;
    parameter ic4 = 1'b0;
    parameter ic5 = 1'b0;
    parameter ic6 = 1'b0;
    localparam delay = 9;
    input wire vcc, gnd, rst, clk;
    input wire a1, a2, a3, a4, a5, a6;
    output wire y1, y2, y3, y4, y5, y6;

    // Treat loss of power like a reset hold
    wire vrst;
    assign vrst = (rst || !vcc);

    nor_1 #(delay, ic1) A(y1, a1, vrst, clk);
    nor_1 #(delay, ic2) B(y2, a2, vrst, clk);
    nor_1 #(delay, ic3) C(y3, a3, vrst, clk);
    nor_1 #(delay, ic4) D(y4, a4, vrst, clk);
    nor_1 #(delay, ic5) E(y5, a5, vrst, clk);
    nor_1 #(delay, ic6) F(y6, a6, vrst, clk);
endmodule
module nor_3(y, a, b, c, rst, clk);
    parameter delay = 9;
    parameter iv = 1'b0;
    input wire a, b, c, rst, clk;

`ifdef TARGET_FPGA
    output reg y = iv;
    reg next_val = iv;
    reg prev_val = iv;
    wire result;
    
    assign result = ~(a|b|c);

    always @(posedge clk)
    begin
        prev_val = y;
        y = next_val;
    end

    always @(negedge clk)
    begin
        next_val = ((result == prev_val) && (y == iv)) ? iv : result;
    end
`else
    output wire y;
    assign #delay y = (rst) ? iv : ~(a|b|c);
`endif
endmodule
module U74HC4002(y1, a1, b1, c1, d1, nc1, gnd, nc2, a2, b2, c2, d2, y2, vcc, rst, clk);
    parameter ic1 = 1'b0;
    parameter ic2 = 1'b0;
    localparam delay = 9;
    input wire vcc, gnd, rst, clk;
    input wire a1, b1, c1, d1, a2, b2, c2, d2;
    input wire nc1, nc2;
    output wire y1, y2;

    // Treat loss of power like a reset hold
    wire vrst;
    assign vrst = (rst || !vcc);

    nor_4 #(delay, ic1) A(y1, a1, b1, c1, d1, vrst, clk);
    nor_4 #(delay, ic2) B(y2, a2, b2, c2, d2, vrst, clk);
endmodule
module core_memory (
	address,
	clock,
	data,
	wren,
	q);

	input	[10:0]  address;
	input	  clock;
	input	[15:0]  data;
	input	  wren;
	output	[15:0]  q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri1	  clock;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

	wire [15:0] sub_wire0;
	wire [15:0] q = sub_wire0[15:0];

	altsyncram	altsyncram_component (
				.address_a (address),
				.clock0 (clock),
				.data_a (data),
				.wren_a (wren),
				.q_a (sub_wire0),
				.aclr0 (1'b0),
				.aclr1 (1'b0),
				.address_b (1'b1),
				.addressstall_a (1'b0),
				.addressstall_b (1'b0),
				.byteena_a (1'b1),
				.byteena_b (1'b1),
				.clock1 (1'b1),
				.clocken0 (1'b1),
				.clocken1 (1'b1),
				.clocken2 (1'b1),
				.clocken3 (1'b1),
				.data_b (1'b1),
				.eccstatus (),
				.q_b (),
				.rden_a (1'b1),
				.rden_b (1'b1),
				.wren_b (1'b0));
	defparam
		altsyncram_component.clock_enable_input_a = "BYPASS",
		altsyncram_component.clock_enable_output_a = "BYPASS",
`ifdef NO_PLI
		altsyncram_component.init_file = "../ram.rif"
`else
		altsyncram_component.init_file = "../ram.hex"
`endif
,
		altsyncram_component.intended_device_family = "Cyclone IV E",
		altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
		altsyncram_component.lpm_type = "altsyncram",
		altsyncram_component.numwords_a = 2048,
		altsyncram_component.operation_mode = "SINGLE_PORT",
		altsyncram_component.outdata_aclr_a = "NONE",
		altsyncram_component.outdata_reg_a = "CLOCK0",
		altsyncram_component.power_up_uninitialized = "FALSE",
		altsyncram_component.read_during_write_mode_port_a = "DONT_CARE",
		altsyncram_component.widthad_a = 11,
		altsyncram_component.width_a = 16,
		altsyncram_component.width_byteena_a = 1;


endmodule
module vjtag (
		output wire       tdi,                // jtag.tdi
		input  wire       tdo,                //     .tdo
		output wire [4:0] ir_in,              //     .ir_in
		input  wire [4:0] ir_out,             //     .ir_out
		output wire       virtual_state_cdr,  //     .virtual_state_cdr
		output wire       virtual_state_sdr,  //     .virtual_state_sdr
		output wire       virtual_state_e1dr, //     .virtual_state_e1dr
		output wire       virtual_state_pdr,  //     .virtual_state_pdr
		output wire       virtual_state_e2dr, //     .virtual_state_e2dr
		output wire       virtual_state_udr,  //     .virtual_state_udr
		output wire       virtual_state_cir,  //     .virtual_state_cir
		output wire       virtual_state_uir,  //     .virtual_state_uir
		output wire       tck                 //  tck.clk
	);

	sld_virtual_jtag #(
		.sld_auto_instance_index ("NO"),
		.sld_instance_index      (2),
		.sld_ir_width            (5)
	) virtual_jtag_0 (
		.tdi                (tdi),                // jtag.tdi
		.tdo                (tdo),                //     .tdo
		.ir_in              (ir_in),              //     .ir_in
		.ir_out             (ir_out),             //     .ir_out
		.virtual_state_cdr  (virtual_state_cdr),  //     .virtual_state_cdr
		.virtual_state_sdr  (virtual_state_sdr),  //     .virtual_state_sdr
		.virtual_state_e1dr (virtual_state_e1dr), //     .virtual_state_e1dr
		.virtual_state_pdr  (virtual_state_pdr),  //     .virtual_state_pdr
		.virtual_state_e2dr (virtual_state_e2dr), //     .virtual_state_e2dr
		.virtual_state_udr  (virtual_state_udr),  //     .virtual_state_udr
		.virtual_state_cir  (virtual_state_cir),  //     .virtual_state_cir
		.virtual_state_uir  (virtual_state_uir),  //     .virtual_state_uir
		.tck                (tck)                 //  tck.clk
	);

endmodule
module ym6045c_cell_1_not (  i2, o3);

	input wire i2;
	output wire o3;
	
	assign o3 = ~i2;

endmodule // ym6045c_cell_1_not
module ym6045c_cell_6_and (  o2, i3, i4);

	output wire o2;
	input wire i3;
	input wire i4;
	
	assign o2 = i3 & i4;

endmodule // ym6045c_cell_6_and
module ym6045c_cell_5_nand (  i1, i2, o3);

	input wire i1;
	input wire i2;
	output wire o3;
	
	assign o3 = ~(i1 & i2);

endmodule // ym6045c_cell_5_nand
module ym6045c_cell_7_buf (  o2, i3);

	output wire o2;
	input wire i3;
	
	assign o2 = i3;

endmodule // ym6045c_cell_7_buf
module ym6045c_cell_4_nand3 (  i1, i2, i3, o4);

	input wire i1;
	input wire i2;
	input wire i3;
	output wire o4;
	
	assign o4 = ~(i1 & i2 & i3);

endmodule // ym6045c_cell_4_nand3
module ym6045c_cell_16_buf (  o2, i4);

	output wire o2;
	input wire i4;
	
	assign o2 = i4;

endmodule // ym6045c_cell_16_buf
module ym6045c_cell_29_and6 (  o1, i2, i3, i4, i5, i6, i7);

	output wire o1;
	input wire i2;
	input wire i3;
	input wire i4;
	input wire i5;
	input wire i6;
	input wire i7;
	
	assign o1 = i2 & i3 & i4 & i5 & i6 & i7;

endmodule // ym6045c_cell_29_and6
module ym6045c_cell_30_nor4 (  o2, i3, i4, i5, i6);

	output wire o2;
	input wire i3;
	input wire i4;
	input wire i5;
	input wire i6;
	
	assign o2 = ~(i3 | i4 | i5 | i6);

endmodule // ym6045c_cell_30_nor4
module ym6045c_cell_19_and4 (  o1, i2, i3, i4, i5);

	output wire o1;
	input wire i2;
	input wire i3;
	input wire i4;
	input wire i5;
	
	assign o1 = i2 & i3 & i4 & i5;

endmodule // ym6045c_cell_19_and4
module ym6045c_cell_10_or (  i2, o3, i4);

	input wire i2;
	output wire o3;
	input wire i4;
	
	assign o3 = i2 | i4;

endmodule // ym6045c_cell_10_or
module ym6045c_cell_8_nor (  o1, i2, i3);

	output wire o1;
	input wire i2;
	input wire i3;
	
	assign o1 = ~(i2 | i3);

endmodule // ym6045c_cell_8_nor
module ym6045c_cell_18_or3 (  o1, i2, i3, i4);

	output wire o1;
	input wire i2;
	input wire i3;
	input wire i4;
	
	assign o1 = i2 | i3 | i4;

endmodule // ym6045c_cell_18_or3
module ym6045c_cell_3_nand4 (  i2h, i2l, i3h, i3l, o4);

	input wire i2h;
	input wire i2l;
	input wire i3h;
	input wire i3l;
	output wire o4;
	
	assign o4 = ~(i2h & i2l & i3h & i3l);

endmodule // ym6045c_cell_3_nand4
module ym6045c_cell_15_and3 (  o1, i2, i3, i4);

	output wire o1;
	input wire i2;
	input wire i3;
	input wire i4;
	
	assign o1 = i2 & i3 & i4;

endmodule // ym6045c_cell_15_and3
module ym6045c_cell_24_nand6 (  i1h, i1l, i2h, i2l, i4h, i4l, o7);

	input wire i1h;
	input wire i1l;
	input wire i2h;
	input wire i2l;
	input wire i4h;
	input wire i4l;
	output wire o7;
	
	assign o7 = ~(i1h & i1l & i2h & i2l & i4h & i4l);

endmodule // ym6045c_cell_24_nand6
module ym6045c_cell_21_or4 (  o1, i2, i3, i4, i5);

	output wire o1;
	input wire i2;
	input wire i3;
	input wire i4;
	input wire i5;
	
	assign o1 = i2 | i3 | i4 | i5;

endmodule // ym6045c_cell_21_or4
module ym6045c_cell_12_nor3 (  o1, i2, i3, i4);

	output wire o1;
	input wire i2;
	input wire i3;
	input wire i4;
	
	assign o1 = ~(i2 | i3 | i4);

endmodule // ym6045c_cell_12_nor3
module ym6045c_cell_22_mux4bit (  i1, o2, i6, i7, i8, i9, o11, o12, i13, i14, i15, i17, o19);

	input wire i1;
	output wire o2;
	input wire i6;
	input wire i7;
	input wire i8;
	input wire i9;
	output wire o11;
	output wire o12;
	input wire i13;
	input wire i14;
	input wire i15;
	input wire i17;
	output wire o19;
	
	assign o2 = i1 ? i7 : i6;
	assign o11 = i1 ? i9 : i8;
	assign o12 = i1 ? i13 : i14;
	assign o19 = i1 ? i17 : i15;

endmodule // ym6045c_cell_22_mux4bit
module ym6045c_cell_26_xnor (  i2, i4, o5);

	input wire i2;
	input wire i4;
	output wire o5;
	
	assign o5 = ~(i2 ^ i4);

endmodule // ym6045c_cell_26_xnor
module ym6045c_cell_28_mux (  i1, o2, i5, i6);

	input wire i1;
	output wire o2;
	input wire i5;
	input wire i6;
	
	assign o2 = i1 ? i6 : i5;

endmodule // ym6045c_cell_28_mux
module ym6045c_cell_36_or8 (  i1h, i1l, i2h, i2l, o3, i7h, i7l, i8h, i8l);

	input wire i1h;
	input wire i1l;
	input wire i2h;
	input wire i2l;
	output wire o3;
	input wire i7h;
	input wire i7l;
	input wire i8h;
	input wire i8l;
	
	assign o3 = i1h | i1l | i2h | i2l | i7h | i7l | i8h | i8l;

endmodule // ym6045c_cell_36_or8
module ym6045c_cell_25_dec2to4 (  i1, o2, o3, i6, o10, o11);

	input wire i1;
	output wire o2;
	output wire o3;
	input wire i6;
	output wire o10;
	output wire o11;
	
	assign o11 = ~i1 & ~i6;
	assign o3 = ~i1 & i6;
	assign o10 = i1 & ~i6;
	assign o2 = i1 & i6;

endmodule // ym6045c_cell_25_dec2to4
module ym6045c_cell_39_oai21 (  o1, i2, i3, i4);

	output wire o1;
	input wire i2;
	input wire i3;
	input wire i4;
	
	assign o1 = ~(i3 & (i2 | i4));

endmodule // ym6045c_cell_39_oai21
module ym6045c_cell_37_nor8 (  i1, i2, i3, i4, o5, i6, i7, i8, i9);

	input wire i1;
	input wire i2;
	input wire i3;
	input wire i4;
	output wire o5;
	input wire i6;
	input wire i7;
	input wire i8;
	input wire i9;
	
	assign o5 = ~(i1 | i2 | i3 | i4 | i6 | i7 | i8 | i9);

endmodule // ym6045c_cell_37_nor8
module ym6045c_cell_14_cnt_bit (  o2, o3, i6, i7, i13, i14, o15, i18);

	output wire o2;
	output wire o3;
	input wire i6;
	input wire i7;
	input wire i13;
	input wire i14;
	output wire o15;
	input wire i18;
	
	reg data;
	
	wire s = data ^ i18;
	assign o15 = data & i18;
	
	assign o2 = data;
	assign o3 = ~data;
	
	always @(posedge i6, negedge i7)
	begin
		if (~i7)
			data <= 1'h0;
		else if (~i14)
			data <= i13;
		else
			data <= s;
	end

endmodule // ym6045c_cell_14_cnt_bit
module ym6045c_cell_9_dffs (  i3, i4, i7, o11, o13);

	input wire i3;
	input wire i4;
	input wire i7;
	output wire o11;
	output wire o13;
	
	reg data;
	
	assign o13 = data;
	assign o11 = ~data;
	
	always @(posedge i3, negedge i7)
	begin
		if (~i7)
			data <= 1'h1;
		else
			data <= i4;
	end

endmodule // ym6045c_cell_9_dffs
module ym6045c_cell_2_dffr (  o2, o4, i9, i11, i13);

	output wire o2;
	output wire o4;
	input wire i9;
	input wire i11;
	input wire i13;
	
	reg data;
	
	assign o4 = data;
	assign o2 = ~data;
	
	always @(posedge i13, negedge i9)
	begin
		if (~i9)
			data <= 1'h0;
		else
			data <= i11;
	end

endmodule // ym6045c_cell_2_dffr
module ym6045c_cell_23_dff (  o2, o5, i10, i11);

	output wire o2;
	output wire o5;
	input wire i10;
	input wire i11;
	
	reg data;
	
	assign o5 = data;
	assign o2 = ~data;
	
	always @(posedge i11)
	begin
		data <= i10;
	end

endmodule // ym6045c_cell_23_dff
module ym6045c_cell_17_sr8 (  i2, o3, o10, o16, o23, o29, o36, o42, o49, i56, i57);

	input wire i2;
	output wire o3;
	output wire o10;
	output wire o16;
	output wire o23;
	output wire o29;
	output wire o36;
	output wire o42;
	output wire o49;
	input wire i56;
	input wire i57;
	
	reg [7:0] data;
	
	assign o3 = data[0];
	assign o10 = data[1];
	assign o16 = data[2];
	assign o23 = data[3];
	assign o29 = data[4];
	assign o36 = data[5];
	assign o42 = data[6];
	assign o49 = data[7];
	
	always @(posedge i57, negedge i2)
	begin
		if (~i2)
			data <= 8'h0;
		else
			data <= { i56, data[7:1] };
	end

endmodule // ym6045c_cell_17_sr8
module ym6045c_cell_38 (  o1, o2, i10, i12);

	output wire o1;
	output wire o2;
	input wire i10;
	input wire i12;
	
	reg data;
	
	assign o1 = ~data;
	assign o2 = data;
	
	always @(negedge i12, negedge i10)
	begin
		if (~i10)
			data <= 1'h0;
		else
			data <= ~data;
	end

endmodule // ym6045c_cell_38
module ym6045c_cell_31 (  i2, i3, i4, i13, o16, o17);

	input wire i2;
	input wire i3;
	input wire i4;
	input wire i13;
	output wire o16;
	output wire o17;
	
	reg data;
	assign o16 = data;
	assign o17 = ~data;
	
	always @(negedge i2, negedge i13)
	begin
		if (~i13)
			data <= 1'h0;
		else
			data <= ~(~(i3 | data) | (i4 & data));
	end

endmodule // ym6045c_cell_31
module ym6045c_cell_32 (  i1, o2);

	input wire i1;
	output wire o2;
	
	assign o2 = i1;

endmodule // ym6045c_cell_32
module ym6045c_cell_35_not (  o1, i2);

	output wire o1;
	input wire i2;
	
	assign o1 = ~i2;

endmodule // ym6045c_cell_35_not
module pad_inout ( read_enable, vout_from_core, vin_to_core, pad );

	input read_enable;
	input vout_from_core;
	output vin_to_core;
	inout pad;

	bufif0 (pad, vout_from_core, read_enable);
	assign vin_to_core = pad;

endmodule // pad_inout
module Z80 (CLK, A, D, n_RFSH, n_M1, n_RESET, n_BUSACK, n_BUSREQ, n_WAIT, n_RD, n_WR, n_IORQ, n_MREQ, n_HALT, n_NMI, n_INT);

	input CLK;
	output [15:0] A;
	inout [7:0] D;
	output n_RFSH;
	output n_M1;
	input n_RESET;
	output n_BUSACK;
	input n_BUSREQ;
	input n_WAIT;
	output n_RD;
	output n_WR;
	output n_IORQ;
	output n_MREQ;
	output n_HALT;
	input n_NMI;
	input n_INT;

	pad_inout DataPads [7:0] ();

endmodule // Z80
module shift_register #(
    parameter WIDTH = 8
)(
    input wire clk,
    input wire rst,
    input wire enable,
    input wire [WIDTH-1:0] data_in,
    output wire [WIDTH-1:0] data_out,
    input wire scan_enable,
    input wire scan_in,
    output wire scan_out
);

    reg [WIDTH-1:0] internal_data;

    // Shift register operation
    always @(posedge clk) begin
        if (rst) begin
            internal_data <= {WIDTH{1'b0}};
        end else if (scan_enable) begin
            if (WIDTH == 1) begin
                internal_data <= scan_in;
            end else begin
                internal_data <= {internal_data[WIDTH-2:0], scan_in};
            end
        end else if (enable) begin
            internal_data <= data_in;
        end
    end

    // Output assignment
    assign data_out = internal_data;
    assign scan_out = internal_data[WIDTH-1];

endmodule
module memory_bank #(
    parameter ADDR_WIDTH = 5,
    parameter DATA_WIDTH = 8,
    parameter MEM_SIZE = 32
)(
    input wire clk,
    input wire rst,
    input wire [ADDR_WIDTH-1:0] address,
    input wire [DATA_WIDTH-1:0] data_in,
    input wire write_enable,
    output reg [DATA_WIDTH-1:0] data_out,
    input wire scan_enable,
    input wire scan_in,
    output wire scan_out
);

    // Generate an array of shift registers for the memory
    wire [DATA_WIDTH-1:0] mem_data_out [0:MEM_SIZE-1];
    wire mem_scan_out [0:MEM_SIZE-1]; 

    genvar i;
    generate
        for (i = 0; i < MEM_SIZE; i = i + 1) begin : memory
            shift_register #(
                .WIDTH(DATA_WIDTH)
            ) mem_cell (
                .clk(clk),
                .rst(rst),
                .enable(write_enable && (address == i)),
                .data_in(data_in),
                .data_out(mem_data_out[i]),
                .scan_enable(scan_enable),
                .scan_in(i == 0 ? scan_in : mem_scan_out[i-1]),
                .scan_out(mem_scan_out[i])
            );
        end
    endgenerate

    // Read operation
    integer idx;
    always @(*) begin
        data_out = {DATA_WIDTH{1'b0}};
        for (idx = 0; idx < MEM_SIZE; idx = idx + 1) begin
            if (address == idx) begin
                data_out = mem_data_out[idx];
            end
        end
        //data_out = mem_data_out[address];
    end

    // Scan chain output
    assign scan_out = mem_scan_out[MEM_SIZE-1];

endmodule
module instruction_decoder (
    input wire [7:0] instruction,
    output reg [3:0] alu_opcode
);

always @(*) begin
    case (instruction[7:4])
        4'b0000: alu_opcode = 4'b0000;    // LDA
        4'b0001: alu_opcode = 4'b0000;    // STA
        4'b0010: alu_opcode = 4'b0000;    // ADD
        4'b0011: alu_opcode = 4'b0001;    // SUB
        4'b0100: alu_opcode = 4'b0010;    // AND
        4'b0101: alu_opcode = 4'b0011;    // OR
        4'b0110: alu_opcode = 4'b0100;    // XOR
        4'b1000: alu_opcode = 4'b0000;    // ADDI
        4'b1001: alu_opcode = 4'b0101;    // LUI
        4'b1010: alu_opcode = 4'b0000;    // SETSEG
        4'b1011: alu_opcode = 4'b0000;    // CSR, CSW
        4'b1111: begin                    // Control and Data Manipulation Instructions
            case (instruction[3:0])
                4'b0110: alu_opcode = 4'b0110;    // SHL
                4'b0111: alu_opcode = 4'b0111;    // SHR
                4'b1000: alu_opcode = 4'b1000;    // ROL
                4'b1001: alu_opcode = 4'b1001;    // ROR
                4'b1100: alu_opcode = 4'b1010;    // DEC
                4'b1101: alu_opcode = 4'b1100;    // CLR
                4'b1110: alu_opcode = 4'b1011;    // INV
                default: alu_opcode = 4'b0000;
            endcase
        end
        default: alu_opcode = 4'b0000;
    endcase
end

endmodule
module SegmentCheck(
  input wire [3:0] seg_addr,
  input wire [7:0] SEGEXE_H,
  input wire [7:0] SEGEXE_L,
  output reg illegal_segment_address
);
  
  always @(*) begin
    if (seg_addr < 8) begin
      illegal_segment_address = SEGEXE_L[seg_addr] == 1'b0;
    end
    else if (seg_addr < 16) begin
      illegal_segment_address = SEGEXE_H[seg_addr-8] == 1'b0;
    end
    else begin
      illegal_segment_address = 1'b1;  // By default, indicate illegal if out of 16
    end
  end

endmodule
module alu (
    input wire [7:0] A,
    input wire [7:0] B,
    input wire [3:0] opcode,
    output reg [7:0] Y
);

always @(*) begin
    case (opcode)
        4'b0000: Y = A + B;               // ADD
        4'b0001: Y = A - B;               // SUB
        4'b0010: Y = A & B;               // AND
        4'b0011: Y = A | B;               // OR
        4'b0100: Y = A ^ B;               // XOR
        4'b0101: Y = B << 4;              // LUI
        4'b0110: Y = A << 1;              // SHL
        4'b0111: Y = A >> 1;              // SHR
        4'b1000: Y = A[6:0] | A[7] << 7;  // ROL
        4'b1001: Y = A[0] << 7 | A[7:1];  // ROR
        4'b1010: Y = A - 1;               // DEC
        4'b1011: Y = ~A;                  // INV
        default: Y = 8'b00000000;         // Default case is CLR
    endcase
end

endmodule
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
);

/*--------------------------------------*/
/* User project is instantiated  here   */
/*--------------------------------------*/

user_proj_example mprj (
`ifdef USE_POWER_PINS
	.vccd1(vccd1),	// User area 1 1.8V power
	.vssd1(vssd1),	// User area 1 digital ground
`endif

    .wb_clk_i(wb_clk_i),
    .wb_rst_i(wb_rst_i),

    // MGMT SoC Wishbone Slave

    .wbs_cyc_i(wbs_cyc_i),
    .wbs_stb_i(wbs_stb_i),
    .wbs_we_i(wbs_we_i),
    .wbs_sel_i(wbs_sel_i),
    .wbs_adr_i(wbs_adr_i),
    .wbs_dat_i(wbs_dat_i),
    .wbs_ack_o(wbs_ack_o),
    .wbs_dat_o(wbs_dat_o),

    // Logic Analyzer

    .la_data_in(la_data_in),
    .la_data_out(la_data_out),
    .la_oenb (la_oenb),

    // IO Pads

    .io_in ({io_in[37:30],io_in[7:0]}),
    .io_out({io_out[37:30],io_out[7:0]}),
    .io_oeb({io_oeb[37:30],io_oeb[7:0]}),

    // IRQ
    .irq(user_irq)
);

endmodule	// user_project_wrapper
module sha256_stream
  (input 	  clk,
   input 	  rst,
   input 	  mode,
   input [511:0]  s_tdata_i,
   input 	  s_tlast_i,
   input 	  s_tvalid_i,
   output 	  s_tready_o,
   output [255:0] digest_o,
   output 	  digest_valid_o);

   reg 		  first_block;

   always @(posedge clk) begin
      if (s_tvalid_i & s_tready_o)
	first_block <= s_tlast_i;

      if (rst) begin
	 first_block <= 1'b1;
      end
   end
   
   sha256_core core
     (.clk     (clk),
      .reset_n (~rst),

      .init(s_tvalid_i & first_block),
      .next(s_tvalid_i & !first_block),
      .mode (mode),

      .block(s_tdata_i),

      .ready(s_tready_o),

      .digest       (digest_o),
      .digest_valid (digest_valid_o));

endmodule
module csa_32x4(
                input wire [31:0]  in1,
                input wire [31:0]  in2,
                input wire [31:0]  in3,
                input wire [31:0]  in4,
                output wire [31:0] sum,
                output wire [31:0] carry
                );

  wire [31:0] 			   sum1;
  wire [31:0] 			   carry1;
  
csa_32x3 csa_32x3_1(
		    .in1(in1),
		    .in2(in2),
		    .in3(in3),
		    .sum(sum1),
		    .carry(carry1)
		    );

csa_32x3 csa_32x3_2(
		    .in1(in4),
		    .in2(sum1),
		    .in3({carry1[30:0], 1'b0}),
		    .sum(sum),
		    .carry(carry)
		    );

endmodule // csa_32x4
module csa_32x3(
                input wire [31:0]  in1,
                input wire [31:0]  in2,
                input wire [31:0]  in3,
                output wire [31:0] sum,
                output wire [31:0] carry
                );

  assign sum = in1 ^ in2 ^ in3;
  assign carry = in1 & in2 | in1 & in3 | in2 & in3;

endmodule // csa_32x3
module sha256_k_constants(
                          input wire  [5 : 0] addr,
                          output wire [31 : 0] K
                         );

  //----------------------------------------------------------------
  // Wires.
  //----------------------------------------------------------------
  reg [31 : 0] tmp_K;


  //----------------------------------------------------------------
  // Concurrent connectivity for ports etc.
  //----------------------------------------------------------------
  assign K = tmp_K;


  //----------------------------------------------------------------
  // addr_mux
  //----------------------------------------------------------------
  always @*
    begin : addr_mux
      case(addr)
        00: tmp_K = 32'h428a2f98;
        01: tmp_K = 32'h71374491;
        02: tmp_K = 32'hb5c0fbcf;
        03: tmp_K = 32'he9b5dba5;
        04: tmp_K = 32'h3956c25b;
        05: tmp_K = 32'h59f111f1;
        06: tmp_K = 32'h923f82a4;
        07: tmp_K = 32'hab1c5ed5;
        08: tmp_K = 32'hd807aa98;
        09: tmp_K = 32'h12835b01;
        10: tmp_K = 32'h243185be;
        11: tmp_K = 32'h550c7dc3;
        12: tmp_K = 32'h72be5d74;
        13: tmp_K = 32'h80deb1fe;
        14: tmp_K = 32'h9bdc06a7;
        15: tmp_K = 32'hc19bf174;
        16: tmp_K = 32'he49b69c1;
        17: tmp_K = 32'hefbe4786;
        18: tmp_K = 32'h0fc19dc6;
        19: tmp_K = 32'h240ca1cc;
        20: tmp_K = 32'h2de92c6f;
        21: tmp_K = 32'h4a7484aa;
        22: tmp_K = 32'h5cb0a9dc;
        23: tmp_K = 32'h76f988da;
        24: tmp_K = 32'h983e5152;
        25: tmp_K = 32'ha831c66d;
        26: tmp_K = 32'hb00327c8;
        27: tmp_K = 32'hbf597fc7;
        28: tmp_K = 32'hc6e00bf3;
        29: tmp_K = 32'hd5a79147;
        30: tmp_K = 32'h06ca6351;
        31: tmp_K = 32'h14292967;
        32: tmp_K = 32'h27b70a85;
        33: tmp_K = 32'h2e1b2138;
        34: tmp_K = 32'h4d2c6dfc;
        35: tmp_K = 32'h53380d13;
        36: tmp_K = 32'h650a7354;
        37: tmp_K = 32'h766a0abb;
        38: tmp_K = 32'h81c2c92e;
        39: tmp_K = 32'h92722c85;
        40: tmp_K = 32'ha2bfe8a1;
        41: tmp_K = 32'ha81a664b;
        42: tmp_K = 32'hc24b8b70;
        43: tmp_K = 32'hc76c51a3;
        44: tmp_K = 32'hd192e819;
        45: tmp_K = 32'hd6990624;
        46: tmp_K = 32'hf40e3585;
        47: tmp_K = 32'h106aa070;
        48: tmp_K = 32'h19a4c116;
        49: tmp_K = 32'h1e376c08;
        50: tmp_K = 32'h2748774c;
        51: tmp_K = 32'h34b0bcb5;
        52: tmp_K = 32'h391c0cb3;
        53: tmp_K = 32'h4ed8aa4a;
        54: tmp_K = 32'h5b9cca4f;
        55: tmp_K = 32'h682e6ff3;
        56: tmp_K = 32'h748f82ee;
        57: tmp_K = 32'h78a5636f;
        58: tmp_K = 32'h84c87814;
        59: tmp_K = 32'h8cc70208;
        60: tmp_K = 32'h90befffa;
        61: tmp_K = 32'ha4506ceb;
        62: tmp_K = 32'hbef9a3f7;
        63: tmp_K = 32'hc67178f2;
      endcase // case (addr)
    end // block: addr_mux
endmodule // sha256_k_constants
module csa_32x6(
                input wire [31:0]  in1,
                input wire [31:0]  in2,
                input wire [31:0]  in3,
                input wire [31:0]  in4,
                input wire [31:0]  in5,
                input wire [31:0]  in6,
                output wire [31:0] sum,
                output wire [31:0] carry
                );

  wire [31:0] 			   sum1;
  wire [31:0] 			   sum2;
  wire [31:0] 			   sum3;
  wire [31:0] 			   carry1;
  wire [31:0] 			   carry2;
  wire [31:0] 			   carry3;
  
csa_32x3 csa_32x3_1(
		    .in1(in1),
		    .in2(in2),
		    .in3(in3),
		    .sum(sum1),
		    .carry(carry1)
		    );

csa_32x3 csa_32x3_2(
		    .in1(in4),
		    .in2(in5),
		    .in3(in6),
		    .sum(sum2),
		    .carry(carry2)
		    );

csa_32x3 csa_32x3_3(
		    .in1(sum1),
		    .in2(sum2),
		    .in3({carry1[30:0], 1'b0}),
		    .sum(sum3),
		    .carry(carry3)
		    );

csa_32x3 csa_32x3_4(
		    .in1(sum3),
		    .in2({carry2[30:0], 1'b0}),
		    .in3({carry3[30:0], 1'b0}),
		    .sum(sum),
		    .carry(carry)
		    );

endmodule // csa_32x6
module fpga_top
(
    // Inputs
     input           clk_i
    ,input           clk_x5_i
    ,input           rst_i

    // Outputs
    ,output          dvi_red_o
    ,output          dvi_green_o
    ,output          dvi_blue_o
    ,output          dvi_clock_o
);

wire  [  7:0]  video_blue_w;
wire           video_hsync_w;
wire           video_vsync_w;
wire  [  7:0]  video_green_w;
wire  [  7:0]  video_red_w;
wire           video_blank_w;


dvi
u_dvi
(
    // Inputs
     .clk_i(clk_i)
    ,.rst_i(rst_i)
    ,.clk_x5_i(clk_x5_i)
    ,.vga_red_i(video_red_w)
    ,.vga_green_i(video_green_w)
    ,.vga_blue_i(video_blue_w)
    ,.vga_blank_i(video_blank_w)
    ,.vga_hsync_i(video_hsync_w)
    ,.vga_vsync_i(video_vsync_w)

    // Outputs
    ,.dvi_red_o(dvi_red_o)
    ,.dvi_green_o(dvi_green_o)
    ,.dvi_blue_o(dvi_blue_o)
    ,.dvi_clock_o(dvi_clock_o)
);


video_gen
u_gen
(
    // Inputs
     .clk_i(clk_i)
    ,.rst_i(rst_i)

    // Outputs
    ,.vga_red_o(video_red_w)
    ,.vga_green_o(video_green_w)
    ,.vga_blue_o(video_blue_w)
    ,.vga_blank_o(video_blank_w)
    ,.vga_hsync_o(video_hsync_w)
    ,.vga_vsync_o(video_vsync_w)
);



endmodule
module reset_gen
(
    input  clk_i,
    output rst_o
);

reg [3:0] count_q = 4'b0;
reg       rst_q   = 1'b1;

always @(posedge clk_i) 
if (count_q != 4'hF)
    count_q <= count_q + 4'd1;
else
    rst_q <= 1'b0;

assign rst_o = rst_q;

endmodule
module artix7_pll
(
    // Inputs
     input           clkref_i

    // Outputs
    ,output          clkout0_o
    ,output          clkout1_o
);





wire clkref_buffered_w;
wire clkfbout_w;
wire clkfbout_buffered_w;
wire pll_clkout0_w;
wire pll_clkout0_buffered_w;
wire pll_clkout1_w;
wire pll_clkout1_buffered_w;

// Input buffering
IBUF IBUF_IN
(
    .I (clkref_i),
    .O (clkref_buffered_w)
);

// Clocking primitive
PLLE2_BASE
#(
    .BANDWIDTH("OPTIMIZED"),      // OPTIMIZED, HIGH, LOW
    .CLKFBOUT_PHASE(0.0),         // Phase offset in degrees of CLKFB, (-360-360)
    .CLKIN1_PERIOD(10.0),         // Input clock period in ns resolution
    .CLKFBOUT_MULT(10),     // VCO=1000MHz

    // CLKOUTx_DIVIDE: Divide amount for each CLKOUT(1-128)
    .CLKOUT0_DIVIDE(20), // CLK0=50MHz
    .CLKOUT1_DIVIDE(4), // CLK1=250MHz

    // CLKOUTx_DUTY_CYCLE: Duty cycle for each CLKOUT
    .CLKOUT0_DUTY_CYCLE(0.5),
    .CLKOUT1_DUTY_CYCLE(0.5),
    .CLKOUT2_DUTY_CYCLE(0.5),
    .CLKOUT3_DUTY_CYCLE(0.5),

    // CLKOUTx_PHASE: Phase offset for each CLKOUT
    .CLKOUT0_PHASE(0.0),
    .CLKOUT1_PHASE(0.0),
    .CLKOUT2_PHASE(0.0),
    .CLKOUT3_PHASE(0.0),

    .DIVCLK_DIVIDE(1),            // Master division value (1-56)
    .REF_JITTER1(0.0),            // Ref. input jitter in UI (0.000-0.999)
    .STARTUP_WAIT("TRUE")         // Delay DONE until PLL Locks ("TRUE"/"FALSE")
)
u_pll
(
    .CLKFBOUT(clkfbout_w),
    .CLKOUT0(pll_clkout0_w),
    .CLKOUT1(pll_clkout1_w),
    .CLKOUT2(),
    .CLKOUT3(),
    .CLKOUT4(),
    .CLKOUT5(),
    .LOCKED(),
    .PWRDWN(1'b0),
    .RST(1'b0),
    .CLKIN1(clkref_buffered_w),
    .CLKFBIN(clkfbout_buffered_w)
);

BUFH u_clkfb_buf
(
    .I(clkfbout_w),
    .O(clkfbout_buffered_w)
);

//-----------------------------------------------------------------
// CLK_OUT0
//-----------------------------------------------------------------
BUFG u_clkout0_buf
(
    .I(pll_clkout0_w),
    .O(pll_clkout0_buffered_w)
);

assign clkout0_o = pll_clkout0_buffered_w;


//-----------------------------------------------------------------
// CLK_OUT1
//-----------------------------------------------------------------
BUFG u_clkout1_buf
(
    .I(pll_clkout1_w),
    .O(pll_clkout1_buffered_w)
);

assign clkout1_o = pll_clkout1_buffered_w;






endmodule
module top
(
    input           clk100mhz,
    output [3:0]    tmds_out_p,
    output [3:0]    tmds_out_n    
);

//-----------------------------------------------------------------
// Implementation
//-----------------------------------------------------------------
wire clk50_w;
wire clk250_w;
wire rst_w;

wire dvi_red_w;
wire dvi_green_w;
wire dvi_blue_w;
wire dvi_clock_w;

artix7_pll
u_pll
(
    // Inputs
    .clkref_i(clk100mhz)

    // Outputs
    ,.clkout0_o(clk50_w)
    ,.clkout1_o(clk250_w)
);

reset_gen
u_rst
(
    .clk_i(clk50_w),
    .rst_o(rst_w)
);

fpga_top
u_top
(
     .clk_i(clk50_w)
    ,.rst_i(rst_w)
    ,.clk_x5_i(clk250_w)

    ,.dvi_red_o(dvi_red_w)
    ,.dvi_green_o(dvi_green_w)
    ,.dvi_blue_o(dvi_blue_w)
    ,.dvi_clock_o(dvi_clock_w)
);


OBUFDS u_buf_b
(
    .O(tmds_out_p[0]),
    .OB(tmds_out_n[0]),
    .I(dvi_blue_w)
);

OBUFDS u_buf_g
(
    .O(tmds_out_p[1]),
    .OB(tmds_out_n[1]),
    .I(dvi_green_w)
);

OBUFDS u_buf_r
(
    .O(tmds_out_p[2]),
    .OB(tmds_out_n[2]),
    .I(dvi_red_w)
);

OBUFDS u_buf_c
(
    .O(tmds_out_p[3]),
    .OB(tmds_out_n[3]),
    .I(dvi_clock_w)
);

endmodule
module dvi_resync
//-----------------------------------------------------------------
// Params
//-----------------------------------------------------------------
#(
    parameter RESET_VAL = 1'b0
)
//-----------------------------------------------------------------
// Ports
//-----------------------------------------------------------------
(
    input  clk_i,
    input  rst_i,
    input  async_i,
    output sync_o
);

(* ASYNC_REG = "TRUE" *) reg sync_ms;
(* ASYNC_REG = "TRUE" *) reg sync_q;

always @ (posedge clk_i or posedge rst_i)
if (rst_i)
begin
    sync_ms  <= RESET_VAL;
    sync_q   <= RESET_VAL;
end
else
begin
    sync_ms  <= async_i;
    sync_q   <= sync_ms;
end

assign sync_o = sync_q;

endmodule
module dvi_framebuffer_fifo
(
    // Inputs
     input           clk_i
    ,input           rst_i
    ,input  [ 31:0]  data_in_i
    ,input           push_i
    ,input           pop_i

    // Outputs
    ,output [ 31:0]  data_out_o
    ,output          accept_o
    ,output          valid_o
);

//-----------------------------------------------------------------
// Registers
//-----------------------------------------------------------------
reg [9:0]   rd_ptr_q;
reg [9:0]   wr_ptr_q;

//-----------------------------------------------------------------
// Write Side
//-----------------------------------------------------------------
wire [9:0] write_next_w = wr_ptr_q + 10'd1;

wire full_w = (write_next_w == rd_ptr_q);

always @ (posedge clk_i or posedge rst_i)
if (rst_i)
    wr_ptr_q <= 10'b0;
// Push
else if (push_i & !full_w)
    wr_ptr_q <= write_next_w;

//-----------------------------------------------------------------
// Read Side
//-----------------------------------------------------------------
wire read_ok_w = (wr_ptr_q != rd_ptr_q);
reg  rd_q;

always @ (posedge clk_i or posedge rst_i)
if (rst_i)
    rd_q <= 1'b0;
else
    rd_q <= read_ok_w;

always @ (posedge clk_i or posedge rst_i)
if (rst_i)
    rd_ptr_q     <= 10'b0;
// Read address increment
else if (read_ok_w && ((!valid_o) || (valid_o && pop_i)))
    rd_ptr_q <= rd_ptr_q + 10'd1;

//-------------------------------------------------------------------
// Read Skid Buffer
//-------------------------------------------------------------------
reg        rd_skid_q;
reg [31:0] rd_skid_data_q;

always @ (posedge clk_i or posedge rst_i)
if (rst_i)
begin
    rd_skid_q <= 1'b0;
    rd_skid_data_q <= 32'b0;
end
else if (valid_o && !pop_i)
begin
    rd_skid_q      <= 1'b1;
    rd_skid_data_q <= data_out_o;
end
else
begin
    rd_skid_q      <= 1'b0;
    rd_skid_data_q <= 32'b0;
end

//-------------------------------------------------------------------
// Combinatorial
//-------------------------------------------------------------------
assign valid_o       = rd_skid_q | rd_q;
assign accept_o      = !full_w;

//-------------------------------------------------------------------
// Dual port RAM
//-------------------------------------------------------------------
wire [31:0] data_out_w;

dvi_framebuffer_dp_ram
u_ram
(
    // Inputs
    .clk0_i(clk_i),
    .rst0_i(rst_i),
    .clk1_i(clk_i),
    .rst1_i(rst_i),

    // Write side
    .addr0_i(wr_ptr_q),
    .wr0_i(push_i & accept_o),
    .data0_i(data_in_i),
    .data0_o(),

    // Read side
    .addr1_i(rd_ptr_q),
    .data1_i(32'b0),
    .wr1_i(1'b0),
    .data1_o(data_out_w)
);

assign data_out_o = rd_skid_q ? rd_skid_data_q : data_out_w;

endmodule
module dvi_framebuffer_dp_ram
(
    // Inputs
     input           clk0_i
    ,input           rst0_i
    ,input  [ 9:0]   addr0_i
    ,input  [ 31:0]  data0_i
    ,input           wr0_i
    ,input           clk1_i
    ,input           rst1_i
    ,input  [ 9:0]   addr1_i
    ,input  [ 31:0]  data1_i
    ,input           wr1_i

    // Outputs
    ,output [ 31:0]  data0_o
    ,output [ 31:0]  data1_o
);

/* verilator lint_off MULTIDRIVEN */
reg [31:0]   ram [1023:0] /*verilator public*/;
/* verilator lint_on MULTIDRIVEN */

reg [31:0] ram_read0_q;
reg [31:0] ram_read1_q;

// Synchronous write
always @ (posedge clk0_i)
begin
    if (wr0_i)
        ram[addr0_i] <= data0_i;

    ram_read0_q <= ram[addr0_i];
end

always @ (posedge clk1_i)
begin
    if (wr1_i)
        ram[addr1_i] <= data1_i;

    ram_read1_q <= ram[addr1_i];
end

assign data0_o = ram_read0_q;
assign data1_o = ram_read1_q;

endmodule
module dvi_serialiser
(
      input       clk_i
    , input       rst_i
    , input       strobe_i
    , input [9:0] data_i
    , output      serial_o
);

`ifndef verilator
ODDR
#(
     .DDR_CLK_EDGE("SAME_EDGE")
    ,.INIT(1'b0)
    ,.SRTYPE("ASYNC")
)
u_ddr_r
(
     .C(clk_i)
    ,.CE(1'b1)
    ,.D1(data_i[0])
    ,.D2(data_i[1])
    ,.Q(serial_o)
    ,.R(1'b0)
    ,.S(1'b0)
);
`else
// Hack - non-functional sim
assign serial_o = clk_i ? data_i[0] : data_i[1];
`endif

endmodule
module rosc_entropy(
                    input wire           clk,
                    input wire           reset_n,

                    input wire           cs,
                    input wire           we,
                    input wire  [7 : 0]  address,
                    input wire  [31 : 0] write_data,
                    output wire [31 : 0] read_data,
                    output wire          error,

                    input wire           discard,
                    input wire           test_mode,
                    output wire          security_error,

                    output wire          entropy_enabled,
                    output wire [31 : 0] entropy_data,
                    output wire          entropy_valid,
                    input wire           entropy_ack,

                    output wire [7 : 0]  debug,
                    input wire           debug_update
                   );


  //----------------------------------------------------------------
  // Concurrent connectivity for ports etc.
  //----------------------------------------------------------------
  assign read_data      = 32'h00000000;
  assign error          = 0;
  assign security_error = 0;

  assign entropy_enabled = 1;
  assign entropy_data    = 32'haa55aa55;
  assign entropy_valid   = 1;

  assign debug           = 8'h42;

endmodule // ringosc_entropy
module avalanche_entropy(
                         input wire           clk,
                         input wire           reset_n,

                         input wire           noise,

                         input wire           cs,
                         input wire           we,
                         input wire  [7 : 0]  address,
                         input wire  [31 : 0] write_data,
                         output wire [31 : 0] read_data,
                         output wire          error,

                         input wire           discard,
                         input wire           test_mode,
                         output wire          security_error,

                         output wire          entropy_enabled,
                         output wire [31 : 0] entropy_data,
                         output wire          entropy_valid,
                         input wire           entropy_ack,

                         output wire [7 : 0]  debug,
                         input wire           debug_update
                        );


  //----------------------------------------------------------------
  // Concurrent connectivity for ports etc.
  //----------------------------------------------------------------
  assign read_data      = 32'h00000000;
  assign error          = 0;
  assign security_error = 0;

  assign entropy_enabled = 1;
  assign entropy_data    = 32'h11223344;
  assign entropy_valid   = 1;

  assign debug           = 8'haa;

endmodule // avalanche_entropy
module pseudo_entropy(
                      input wire           clk,
                      input wire           reset_n,

                      input wire           enable,

                      output wire [31 : 0] raw_entropy,
                      output wire [31 : 0] stats,

                      output wire          enabled,
                      output wire          entropy_syn,
                      output wire [31 : 0] entropy_data,
                      input wire           entropy_ack
                     );


  //----------------------------------------------------------------
  // Concurrent connectivity for ports etc.
  //----------------------------------------------------------------
  assign enabled      = enable;

  assign raw_entropy  = enable ? 32'h00ff00ff : 32'h00000000;
  assign stats        = enable ? 32'hff00ff00 : 32'h00000000;

  assign entropy_syn  = enable;
  assign entropy_data = enable ? 32'hf1e2d3c4 : 32'h00000000;

endmodule // pseudo_entropy
module memory_mux (
	input select,

	input enable_0,
	input command_0,
	input [31:0] address_0,
	input [31:0] write_data_0,
	input [3:0]  write_mask_0,
	output [31:0] read_data_0,
	output valid_0,
	
	input enable_1,
	input command_1,
	input [31:0] address_1,
	input [31:0] write_data_1,
	input [3:0]  write_mask_1,
	output [31:0] read_data_1,
	output valid_1,

	output enable,
	output command,
	output [31:0] address,
	output [31:0] write_data,
	output [3:0] write_mask,
	input [31:0] read_data,
	input valid
);

	assign enable = select ? enable_1 : enable_0;
	assign command = select ? command_1 : command_0;
	assign address = select ? address_1 : address_0;
	assign write_data = select ? write_data_1 : write_data_0;
	assign write_mask = select ? write_mask_1 : write_mask_0;
	assign read_data_1 = read_data;
	assign read_data_0 = read_data;
	assign valid_1 =  select ? valid : 1'b0;
	assign valid_0 = !select ? valid : 1'b0;

endmodule
module branch_jump (
	output branch_taken,
	output [31:0] branch_target,

	output jump,
	output [31:0] jump_target,

	input [31:0] inst,
	input [31:0] pc,
	input [31:0] rd1,
	input [31:0] alu_out
);

	wire [6:0] opcode = inst[6:0];
	wire [2:0] funct3 = inst[9:7];
	wire [11:0] split_imm = {inst[31:27], inst[16:10]};
	wire [31:0] sext_split_imm = split_imm[11] ? {20'hFFFFF, split_imm} : {20'h0, split_imm};

	assign jump = (opcode == `OPCODE_J ||
	               opcode == `OPCODE_JAL ||
	               opcode == `OPCODE_JALR);

	wire [31:0] j_offset = inst[31] ? {6'h3F, inst[31:7], 1'b0} : {6'h0, inst[31:7], 1'b0};

	assign jump_target = (opcode == `OPCODE_J || opcode == `OPCODE_JAL) ? j_offset + pc : rd1;

	/* branch */
	assign branch_target = pc + ($signed(sext_split_imm) << 1);
	
	reg branch_sat;

	always @ (*) begin
		case (funct3)
			`F3_BEQ: branch_sat = (alu_out == 0);
			`F3_BNE: branch_sat = (alu_out != 0);
			`F3_BLT: branch_sat = (alu_out == 1);
			`F3_BGE: branch_sat = (alu_out != 1);
			`F3_BLTU: branch_sat = (alu_out == 1);
			`F3_BGEU: branch_sat = (alu_out != 1);
			default: branch_sat = 0;
		endcase
	end

	assign branch_taken = branch_sat && (opcode == `OPCODE_BRANCH);

endmodule
module multiplier (
	output [31:0] multiplier_result,
	input [31:0] op1,
	input [31:0] op2,
	input [1:0] mul_sel
);
	wire [63:0] sext_op1 = op1[31] ? {32'hFFFFFFFF, op1} : {32'h0, op1};
	wire [63:0] sext_op2 = op2[31] ? {32'hFFFFFFFF, op2} : {32'h0, op2};

	reg [63:0] result;

	always @ (*) begin
		case (mul_sel)
			`MUL_LO, `MUL_HI:
				result = $signed(sext_op1) * $signed(sext_op2);
			`MUL_HI_SU:
				result = $signed(sext_op1) * {32'h0, op2};
			`MUL_HI_UU:
				result = {32'h0, op1} * {32'h0, op2};
			default:
				result = 0;
		endcase
	end

	assign multiplier_result = (mul_sel == `MUL_LO) ? result[31:0] : result[63:0];
endmodule