dakies/OSS_Verilog huggingface dataset:
module WReg(clk,reset,Ins,V1,V2,AO,byte_addr,RD,HI,LO,PC,PC8,CP0_RD,Ins_W,V1_W,V2_W,AO_W,byte_addr_W,RD_W,HI_W,LO_W,PC_W,PC8_W,CP0_RD_W);
//interface
    input clk;
    input reset;

    input [31:0] Ins;
	input [31:0] V1;
	input [31:0] V2;
    input [31:0] AO;
	input [1:0] byte_addr;
    input [31:0] RD;
	input [31:0] HI;
	input [31:0] LO;

    input [31:0] PC;
    input [31:0] PC8;

    input [31:0] CP0_RD;
    
    output reg [31:0] Ins_W;
	output reg [31:0] V1_W;
	output reg [31:0] V2_W;
    output reg [31:0] AO_W;
	output reg [1:0] byte_addr_W;
    output reg [31:0] RD_W;
	output reg [31:0] HI_W;
	output reg [31:0] LO_W;

    output reg [31:0] PC_W;
    output reg [31:0] PC8_W;

    output reg [31:0] CP0_RD_W;
    
//sequential logic
    /*
	initial
		begin
			Ins_W=0;
			V1_W=0;
			V2_W=0;
            AO_W=0;
			byte_addr_W=0;
			RD_W=0;
			HI_W=0;
			LO_W=0;
			PC_W=0;
			PC8_W=0;
            CP0_RD_W=0;
		end
	*/
    
    always @(posedge clk)
        begin
            if(reset)
                begin
                    Ins_W<=0;
					V1_W<=0;
					V2_W<=0;
                    AO_W<=0;
					byte_addr_W<=0;
                    RD_W<=0;
					HI_W<=0;
					LO_W<=0;
                    PC_W<=0;
                    PC8_W<=0;
                    CP0_RD_W<=0;
                end
            else
                begin
                    Ins_W<=Ins;
					V1_W<=V1;
					V2_W<=V2;
                    AO_W<=AO;
					byte_addr_W<=byte_addr;
                    RD_W<=RD;
					HI_W<=HI;
					LO_W<=LO;
                    PC_W<=PC;
                    PC8_W<=PC8;
                    CP0_RD_W<=CP0_RD;
                end
        end

endmodule
module DReg(clk,reset,stall,branch,Ins,PC,ExcCode,Ins_D,PC_D,ExcCode_D,BD_D);
//interface
    input clk;
    input reset;
    input stall;
    input branch;

    input [31:0] Ins;
    input [31:0] PC;

    input [6:2] ExcCode;

    output reg [31:0] Ins_D;
    output reg [31:0] PC_D;
    
    output reg [6:2] ExcCode_D;
    output reg BD_D;

//sequential logic	
    /*
	initial
		begin
			Ins_D=0;
            PC_D=0;
            ExcCode_D=0;
            BD_D=0;
		end
    */
    
    always @(posedge clk)
        begin
            if(reset)
                begin
                    Ins_D<=0;
                    PC_D<=0;        //PC_D doesn't need to stick any PC,so it can be set zero.
                    ExcCode_D<=0;
                    BD_D<=0;
                end
            else if(stall)
                begin
                    Ins_D<=Ins_D;
                    PC_D<=PC_D;
                    ExcCode_D<=ExcCode_D;
                    BD_D<=BD_D;
                end
            else
                begin
                    Ins_D<=Ins;
                    PC_D<=PC;
                    ExcCode_D<=ExcCode;
                    BD_D<=branch;   //BD is stuck on Ins_F when Ins_D is branch
                end
        end

endmodule
module tb_mips;

	// Inputs
	reg clk;
	reg reset;
	reg RxD;
	reg [7:0] dip_switch7;
	reg [7:0] dip_switch6;
	reg [7:0] dip_switch5;
	reg [7:0] dip_switch4;
	reg [7:0] dip_switch3;
	reg [7:0] dip_switch2;
	reg [7:0] dip_switch1;
	reg [7:0] dip_switch0;
	reg [7:0] user_key;

	// Outputs
	wire TxD;
	wire [31:0] lights;
	wire [7:0] digital_tube0;
	wire [7:0] digital_tube1;
	wire [7:0] digital_tube2;
	wire [3:0] digital_Sel0;
	wire [3:0] digital_Sel1;
	wire [3:0] digital_Sel2;

	// Instantiate the Unit Under Test (UUT)
	mips uut (
		.clk(clk), 
		.reset(reset), 
		.RxD(RxD), 
		.dip_switch7(dip_switch7), 
		.dip_switch6(dip_switch6), 
		.dip_switch5(dip_switch5), 
		.dip_switch4(dip_switch4), 
		.dip_switch3(dip_switch3), 
		.dip_switch2(dip_switch2), 
		.dip_switch1(dip_switch1), 
		.dip_switch0(dip_switch0), 
		.user_key(user_key), 
		.TxD(TxD), 
		.lights(lights), 
		.digital_tube0(digital_tube0), 
		.digital_tube1(digital_tube1), 
		.digital_tube2(digital_tube2), 
		.digital_Sel0(digital_Sel0), 
		.digital_Sel1(digital_Sel1), 
		.digital_Sel2(digital_Sel2)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		reset = 1;
		RxD = 0;
		dip_switch7 = 0;
		dip_switch6 = 0;
		dip_switch5 = 0;
		dip_switch4 = 0;
		dip_switch3 = 0;
		dip_switch2 = 0;
		dip_switch1 = 0;
		dip_switch0 = 0;
		user_key = 0;

		// Wait 100 ns for global reset to finish
		#100;
        reset=0;
		// Add stimulus here
		#10000 $finish;
	end
	
	always #5 clk=~clk;
      
endmodule
module RS_D_MUX(RS_D_Sel,RD1,RF_WD_E,RF_WD_M,RF_WD_W,RS_D);
//input
    input [31:0] RS_D_Sel;

    input [31:0] RD1;
    input [31:0] RF_WD_E;
    input [31:0] RF_WD_M;
    input [31:0] RF_WD_W;

//output
    output reg [31:0] RS_D;

//logic
    parameter E=1,
              M=2,
              W=3;

    always @(*)
        begin
            RS_D=RD1;
            case(RS_D_Sel)
                E:RS_D=RF_WD_E;
                M:RS_D=RF_WD_M;
                W:RS_D=RF_WD_W;
            endcase
        end

endmodule
module RT_D_MUX(RT_D_Sel,RD2,RF_WD_E,RF_WD_M,RF_WD_W,RT_D);
//input
    input [31:0] RT_D_Sel;

    input [31:0] RD2;
    input [31:0] RF_WD_E;
    input [31:0] RF_WD_M;
    input [31:0] RF_WD_W;

//output
    output reg [31:0] RT_D;

//logic
    parameter E=1,
              M=2,
              W=3;

    always @(*)
        begin
            RT_D=RD2;
            case(RT_D_Sel)
                E:RT_D=RF_WD_E;
                M:RT_D=RF_WD_M;
                W:RT_D=RF_WD_W;
            endcase
        end

endmodule
module RS_E_MUX(RS_E_Sel,V1_E,RF_WD_M,RF_WD_W,RS_E);
//input
    input [31:0] RS_E_Sel;

    input [31:0] V1_E;
    input [31:0] RF_WD_M;
    input [31:0] RF_WD_W;

//output
    output reg [31:0] RS_E;

//logic
    parameter E=1,
              M=2,
              W=3;

    always @(*)
        begin
            RS_E=V1_E;
            case(RS_E_Sel)
                M:RS_E=RF_WD_M;
                W:RS_E=RF_WD_W;
            endcase
        end

endmodule
module RT_E_MUX(RT_E_Sel,V2_E,RF_WD_M,RF_WD_W,RT_E);
//input
    input [31:0] RT_E_Sel;

    input [31:0] V2_E;
    input [31:0] RF_WD_M;
    input [31:0] RF_WD_W;

//output
    output reg [31:0] RT_E;

//logic
    parameter E=1,
              M=2,
              W=3;

    always @(*)
        begin
            RT_E=V2_E;
            case(RT_E_Sel)
                M:RT_E=RF_WD_M;
                W:RT_E=RF_WD_W;
            endcase
        end

endmodule
module RS_M_MUX(RS_M_Sel,V1_M,RF_WD_W,RS_M);
//input
    input [31:0] RS_M_Sel;

    input [31:0] V1_M;
    input [31:0] RF_WD_W;

//output
    output reg [31:0] RS_M;

//logic
    parameter E=1,
              M=2,
              W=3;

    always @(*)
        begin
            RS_M=V1_M;
            case(RS_M_Sel)
                W:RS_M=RF_WD_W;
            endcase
        end

endmodule
module RT_M_MUX(RT_M_Sel,V2_M,RF_WD_W,RT_M);
//input
    input [31:0] RT_M_Sel;

    input [31:0] V2_M;
    input [31:0] RF_WD_W;

//output
    output reg [31:0] RT_M;

//logic
    parameter E=1,
              M=2,
              W=3;

    always @(*)
        begin
            RT_M=V2_M;
            case(RT_M_Sel)
                W:RT_M=RF_WD_W;
            endcase
        end

endmodule
module RDP(byte_op,half_op,unsigned_op,lwr,byte_addr,RD_RAW,V2,RD); //RD's processor
//input
    input byte_op;
    input half_op;
    input unsigned_op;
	
	input lwr;

    input [1:0] byte_addr;
    
    input [31:0] RD_RAW;
	input [31:0] V2;
//output
    output reg [31:0] RD;

//load
	always @(*)
		begin
			if(lwr)
				begin
					case(byte_addr)
						0:RD=RD_RAW;
						1:RD={V2[31:24],RD_RAW[31:8]};
						2:RD={V2[31:16],RD_RAW[31:16]};
						3:RD={V2[31:8],RD_RAW[31:24]};
					endcase
				end
			else if(byte_op)
				begin
					if(unsigned_op)RD=RD_RAW[(byte_addr*8)+:8];
					else RD=$signed(RD_RAW[(byte_addr*8)+:8]);
				end
			else if(half_op)
				begin
					if(unsigned_op)RD=RD_RAW[(byte_addr*8)+:16];
					else RD=$signed(RD_RAW[(byte_addr*8)+:16]);
				end
			else RD=RD_RAW;
		end
    
endmodule
module IM(clk,PC,Ins);
//interface
	input clk;

	input [31:0] PC;
	
	output [31:0] Ins;
	
//combinational logic
	wire [10:0] addr;	//the binary width of 2048 is 11
	
	//reg [31:0] InsMem[0:2047];
	
	//integer i;
	
	/*
	initial				//set IM to all-zero and get Ins from code.txt
		begin
			i=0;
			while(i<2048)
				begin
					InsMem[i]=0;
					i=i+1;
				end
			$readmemh("code.txt",InsMem);
			$readmemh("code_handler.txt",InsMem,1120,2047);
		end
	*/
	
	assign addr=(PC-32'h0000_3000)>>2;	
	//assign Ins=InsMem[addr];
	
	IP_IM InsMem (
		.clka(clk),			// input clka
		.wea(4'b0000), 		 	// input [3 : 0] wea
		.addra(addr), 		// input [10 : 0] addra
		.dina(0), 			// input [31 : 0] dina
		.douta(Ins) 		// output [31 : 0] douta
	);
	
endmodule
module Bridge(We,IRQ_Timer,IRQ_UART,IRQ_Switch,IRQ_Key,ADDR,WD,Timer_RD,UART_RD,Switch_RD,LED_RD,Tube_RD,Key_RD,Pr_IP,Pr_RD,PrWe,CS,Pr_ADDR,Pr_WD,UART_ADDR);
//input
    input We;                //whether to write peripheral devices
    input IRQ_Timer;         //peripheral devices' interrupt signal
    input IRQ_UART;
    input IRQ_Switch;
    input IRQ_Key;
    
    input [31:0] ADDR;
    input [31:0] WD;

    input [31:0] Timer_RD;
    input [31:0] UART_RD;
    input [31:0] Switch_RD;
    input [31:0] LED_RD;
    input [31:0] Tube_RD;
    input [31:0] Key_RD;

//output
//intern
    output [15:10] Pr_IP;
    output reg [31:0] Pr_RD;
//extern
    output PrWe; 
    output reg [31:0] CS;

    output [31:0] Pr_ADDR;
    output [31:0] Pr_WD;

    output [4:2] UART_ADDR;

//combinational logic
    parameter Timer=0,
              UART=1,
              Switch=2,
              LED=3,
              Tube=4,
              Key=5;

    assign Pr_IP={2'b0,IRQ_Key,IRQ_Switch,IRQ_UART,IRQ_Timer};

    assign PrWe=We;
    assign Pr_ADDR=ADDR;
    assign Pr_WD=WD;

    assign UART_ADDR=(ADDR-32'h0000_7f10)>>2;

    always @(*)
        begin
            if(ADDR>=32'h0000_7F00&&ADDR<=32'h0000_7F0B)
                begin
                    CS=Timer;
                    Pr_RD=Timer_RD;
                end
            else if(ADDR>=32'h0000_7F10&&ADDR<=32'h0000_7F2B)
                begin
                    CS=UART;
                    Pr_RD=UART_RD;
                end
            else if(ADDR>=32'h0000_7F2C&&ADDR<=32'h0000_7F33)
                begin
                    CS=Switch;
                    Pr_RD=Switch_RD;
                end
            else if(ADDR>=32'h0000_7F34&&ADDR<=32'h0000_7F37)
                begin
                    CS=LED;
                    Pr_RD=LED_RD;
                end
            else if(ADDR>=32'h0000_7F38&&ADDR<=32'h0000_7F3F)
                begin
                    CS=Tube;
                    Pr_RD=Tube_RD;
                end
            else if(ADDR>=32'h0000_7F40&&ADDR<=32'h0000_7F43)
                begin
                    CS=Key;
                    Pr_RD=Key_RD;
                end
            else
                begin
                    CS=-1;
                    Pr_RD=-1;
                end
        end

endmodule
module RF(clk,reset,RFWe,Ins,A3,RF_WD,WPC,RD1,RD2);
//interface
	input clk;
	input reset;
	
	input RFWe;
	
	input [31:0] Ins;
	input [4:0] A3;
	input [31:0] RF_WD;
	
	input [31:0] WPC;
	
	output [31:0] RD1;
	output [31:0] RD2;

//sequential logic
	reg [31:0] RFMem[0:31];
	
	wire [4:0] A1,A2;

	integer i;
	
	/*
	initial
		begin
			i=0;
			while(i<32)
				begin
					RFMem[i]=0;	//RFMem can be modified inside function
					i=i+1;
				end
		end
	*/

	assign A1=Ins[25:21],
		   A2=Ins[20:16];
	
	assign RD1=RFMem[A1];
	assign RD2=RFMem[A2];

	always @(posedge clk)
		begin
			RFMem[A3]<=RFMem[A3];
			if(reset)
				begin
					i=0;
					while(i<32)
						begin
							RFMem[i]<=0;	//RFMem can be modified inside function
							i=i+1;
						end
				end
			else if(RFWe&&A3!=0)
				begin
					RFMem[A3]<=RF_WD;
					//$display("%d@%h: $%d <= %h", $time, WPC, A3,RF_WD);
				end
		end
		
endmodule
module RF(clk,reset,RFWe,Ins,A3,RF_WD,WPC,RD1,RD2,t3);
//interface
	input clk;
	input reset;
	
	input RFWe;
	
	input [31:0] Ins;
	input [4:0] A3;
	input [31:0] RF_WD;
	
	input [31:0] WPC;
	
	output [31:0] RD1;
	output [31:0] RD2;

	output [31:0] t3;

//sequential logic
	reg [31:0] RFMem[0:31];
	
	wire [4:0] A1,A2;

	integer i;
	
	/*
	initial
		begin
			i=0;
			while(i<32)
				begin
					RFMem[i]=0;	//RFMem can be modified inside function
					i=i+1;
				end
		end
	*/

	assign A1=Ins[25:21],
		   A2=Ins[20:16];
	
	assign RD1=RFMem[A1];
	assign RD2=RFMem[A2];
	
	assign t3=RFMem[11];
	
	wire [31:0] k0_detect;
	
	assign k0_detect=RFMem[26];

	always @(posedge clk)
		begin
			RFMem[A3]<=RFMem[A3];
			if(reset)
				begin
					i=0;
					while(i<32)
						begin
							RFMem[i]<=0;	//RFMem can be modified inside function
							i=i+1;
						end
				end
			else if(RFWe&&A3!=0)
				begin
					RFMem[A3]<=RF_WD;
					//$display("%d@%h: $%d <= %h", $time, WPC, A3,RF_WD);
				end
		end
		
endmodule
module configuration(
    input clock,
    input DCVideoConfig dcVideoConfig,
    inout _480p_active_n,
    input forceVGAMode,
    input force_generate,
    output reg line_doubler,
    output reg [3:0] clock_config_S,
    output reg config_changed
);
    reg prev_mode = 1'b0;
    reg mode = 1'b0;
    reg _480p_active_n_reg = 1'bz;

    assign _480p_active_n = _480p_active_n_reg;

    always @(posedge clock) begin
        if (prev_mode != mode) begin
            config_changed <= 1'b1;
        end else begin
            config_changed <= 1'b0;
        end

        if (force_generate || forceVGAMode || ~_480p_active_n) begin
            clock_config_S <= dcVideoConfig.ICS644_settings_p;
            line_doubler <= 1'b0;
            mode <= 1'b1;
        end else begin
            clock_config_S <= dcVideoConfig.ICS644_settings_i;
            line_doubler <= 1'b1;
            mode <= 1'b0;
        end

        _480p_active_n_reg <= forceVGAMode ? 1'b0 : 1'bz;
        prev_mode <= mode;
    end

endmodule
module ram (
    data,
    rdaddress,
    rdclock,
    wraddress,
    wrclock,
    wren,
    q);

    input	[23:0]  data;
    input	[`RAM_WIDTH-1:0]  rdaddress;
    input	  rdclock;
    input	[`RAM_WIDTH-1:0]  wraddress;
    input	  wrclock;
    input	  wren;
    output	[23:0]  q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
    tri1	  wrclock;
    tri0	  wren;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

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

    altsyncram	altsyncram_component (
                .address_a (wraddress),
                .address_b (rdaddress),
                .clock0 (wrclock),
                .clock1 (rdclock),
                .data_a (data),
                .wren_a (wren),
                .q_b (sub_wire0),
                .aclr0 (1'b0),
                .aclr1 (1'b0),
                .addressstall_a (1'b0),
                .addressstall_b (1'b0),
                .byteena_a (1'b1),
                .byteena_b (1'b1),
                .clocken0 (1'b1),
                .clocken1 (1'b1),
                .clocken2 (1'b1),
                .clocken3 (1'b1),
                .data_b ({24{1'b1}}),
                .eccstatus (),
                .q_a (),
                .rden_a (1'b1),
                .rden_b (1'b1),
                .wren_b (1'b0));
    defparam
        altsyncram_component.address_aclr_b = "NONE",
        altsyncram_component.address_reg_b = "CLOCK1",
        altsyncram_component.clock_enable_input_a = "BYPASS",
        altsyncram_component.clock_enable_input_b = "BYPASS",
        altsyncram_component.clock_enable_output_b = "BYPASS",
        altsyncram_component.intended_device_family = "Cyclone 10 LP",
        altsyncram_component.lpm_type = "altsyncram",
        altsyncram_component.maximum_depth = `RAM_MAX_DEPTH,
        altsyncram_component.numwords_a = `RAM_NUMWORDS,
        altsyncram_component.numwords_b = `RAM_NUMWORDS,
        altsyncram_component.operation_mode = "DUAL_PORT",
        altsyncram_component.outdata_aclr_b = "NONE",
        altsyncram_component.outdata_reg_b = "CLOCK1",
        altsyncram_component.power_up_uninitialized = "FALSE",
        altsyncram_component.widthad_a = `RAM_WIDTH,
        altsyncram_component.widthad_b = `RAM_WIDTH,
        altsyncram_component.width_a = 24,
        altsyncram_component.width_b = 24,
        altsyncram_component.width_byteena_a = 1;
endmodule
module text_ram (
	data,
	rdaddress,
	rdclock,
	wraddress,
	wrclock,
	wren,
	q);

	input	[7:0]  data;
	input	[9:0]  rdaddress;
	input	  rdclock;
	input	[9:0]  wraddress;
	input	  wrclock;
	input	  wren;
	output	[7:0]  q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri1	  wrclock;
	tri0	  wren;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

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

	altsyncram	altsyncram_component (
				.address_a (wraddress),
				.address_b (rdaddress),
				.clock0 (wrclock),
				.clock1 (rdclock),
				.data_a (data),
				.wren_a (wren),
				.q_b (sub_wire0),
				.aclr0 (1'b0),
				.aclr1 (1'b0),
				.addressstall_a (1'b0),
				.addressstall_b (1'b0),
				.byteena_a (1'b1),
				.byteena_b (1'b1),
				.clocken0 (1'b1),
				.clocken1 (1'b1),
				.clocken2 (1'b1),
				.clocken3 (1'b1),
				.data_b ({8{1'b1}}),
				.eccstatus (),
				.q_a (),
				.rden_a (1'b1),
				.rden_b (1'b1),
				.wren_b (1'b0));
	defparam
		altsyncram_component.address_aclr_b = "NONE",
		altsyncram_component.address_reg_b = "CLOCK1",
		altsyncram_component.clock_enable_input_a = "BYPASS",
		altsyncram_component.clock_enable_input_b = "BYPASS",
		altsyncram_component.clock_enable_output_b = "BYPASS",
		altsyncram_component.init_file = "ram/text_ram.mif",
		altsyncram_component.intended_device_family = "Cyclone 10 LP",
		altsyncram_component.lpm_type = "altsyncram",
		altsyncram_component.numwords_a = 1024,
		altsyncram_component.numwords_b = 1024,
		altsyncram_component.operation_mode = "DUAL_PORT",
		altsyncram_component.outdata_aclr_b = "NONE",
		altsyncram_component.outdata_reg_b = "CLOCK1",
		altsyncram_component.power_up_uninitialized = "FALSE",
		altsyncram_component.widthad_a = 10,
		altsyncram_component.widthad_b = 10,
		altsyncram_component.width_a = 8,
		altsyncram_component.width_b = 8,
		altsyncram_component.width_byteena_a = 1;


endmodule
module osc (
	clkout,
	oscena);	

	output		clkout;
	input		oscena;
endmodule
module Signal_CrossDomain(
    input SignalIn_clkA,
    input clkB,
    output SignalOut_clkB
);

// We use a four-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain
reg [3:0] SyncA_clkB;
always @(posedge clkB) begin 
    SyncA_clkB[0] <= SignalIn_clkA;
    SyncA_clkB[1] <= SyncA_clkB[0];
    SyncA_clkB[2] <= SyncA_clkB[1];
    SyncA_clkB[3] <= SyncA_clkB[2];
end

assign SignalOut_clkB = SyncA_clkB[3];  // new signal synchronized to (=ready to be used in) clkB domain
endmodule
module startup(
    input clock,
    input nreset,
    output reg ready,
    input [31:0] startup_delay
);
    reg startup_done = 0;
    reg [31:0] counter;

    initial begin
        ready <= 0;
        counter <= 0;
    end

    always @ (posedge clock or negedge nreset)
    begin
        if (~nreset) begin
            ready <= 0;
            counter <= 0;
        end else begin
            counter <= #1 counter + 1;
            
            if (startup_done || counter == startup_delay) begin
                ready <= 1;
                startup_done <= 1;
            end
        end
    end
    
endmodule
module edge_detect(
    input async_sig,
    input clk,
    output reg rise,
    output reg fall
);

reg [1:3] resync;

always @(posedge clk) begin
    rise <= resync[2] && !resync[3];
    fall <= resync[3] && !resync[2];
    resync <= { async_sig, resync[1:2] };
end

endmodule
module LEDdim(
    input clk,
    output LED
);
    parameter BITPOS = 2;

    reg [BITPOS:0] cnt;
    reg _led;

    always @(posedge clk) begin
        cnt <= cnt + 1'b1;
        if (cnt == 0) begin
            _led <= 1'b1;
        end else begin
            _led <= 1'b0;
        end
    end

    assign LED = _led;
endmodule
module LEDglow(
    input clk,
    output LED
);
    parameter BITPOS = 23;

    reg [BITPOS:0] cnt;

    always @(posedge clk) cnt <= cnt + 1'b1;
    wire [3:0] PWM_input = cnt[BITPOS] ? cnt[BITPOS-1:BITPOS-4] : ~cnt[BITPOS-1:BITPOS-4];    // ramp the PWM input up and down

    reg [4:0] PWM;
    always @(posedge clk) PWM <= PWM[3:0]+PWM_input;

    assign LED = PWM[4];
endmodule
module Flag_CrossDomain(
    input clkA,
    input FlagIn_clkA,
    //output Busy_clkA,
    input clkB,
    output FlagOut_clkB
);
    parameter INIT_STATE = 0;

    reg data_out = INIT_STATE;
    reg [3:0] rCount;
    reg [2:0] data_out_reg;

    assign FlagOut_clkB = data_out_reg[2];

    always @(posedge clkA) begin
        if (FlagIn_clkA) begin
            rCount <= 4'b1000;
            data_out <= 1'b1;
        end else if (rCount > 0) begin
            rCount <= rCount - 1'b1;
        end else begin
            data_out <= 1'b0;
        end
    end

    always @(posedge clkB) begin
        data_out_reg <= { data_out_reg[1], data_out_reg[0], data_out };
    end
endmodule
module video2ram_tb;


  reg clkIn = 0;
  reg clkOut = 0;
  reg [11:0] counterX;
  reg [11:0] counterY;

  wire [23:0] wrdata;
  wire [23:0] rddata;
  wire [14:0] wraddr;
  wire wren;
  wire wrclock;
  wire starttriggerIn;

  wire [14:0] rdaddr;
  wire starttriggerOut;

  wire HSYNC;
  wire VSYNC;
  wire DE;
  wire CLOCK;
  
  wire [23:0] video_out;

  video2ram video2ram(
    .clock(clkIn),
    .R(8'd0),
    .G(8'd0),
    .B(8'd0),
    .counterX(counterX),
    .counterY(counterY),
    .line_doubler(1'b0),
    .wrdata(wrdata),
    .wraddr(wraddr),
    .wren(wren),
    .wrclock(wrclock),
    .starttrigger(starttriggerIn)
  );

  Flag_CrossDomain trigger(
    .clkA(clkIn),
    .FlagIn_clkA(starttriggerIn),
    .clkB(clkOut),
    .FlagOut_clkB(starttriggerOut)
  );

  ram2video ram2video(
    .starttrigger(starttriggerOut),
    .clock(clkOut),
    .reset(1'b1),
    .line_doubler(1'b0),
    .add_line(1'b0),
    .rddata(rddata),
    .hsync(HSYNC),
    .vsync(VSYNC),
    .DrawArea(DE),
    .videoClock(CLOCK),
    .rdaddr(rdaddr),
    .video_out(video_out)
  );

`ifdef _1080p_
  initial $display("1080p");
  always #250 clkIn = ~clkIn;
  always #91 clkOut = ~clkOut;
`endif

`ifdef _960p_
  initial $display("960p");
  always #2000 clkIn = ~clkIn;
  always #1001 clkOut = ~clkOut;
`endif

`ifdef _VGA_
  initial $display("VGA");
  always #400 clkIn = ~clkIn;
  always #429 clkOut = ~clkOut;
`endif

  always @(posedge clkIn) begin
    if (counterX < 858 - 1) begin
      counterX <= counterX + 1;
    end else begin
      counterX <= 0;
      if (counterY < 525 - 1) begin
        //$display("y:%0d ay:%0d ay2:%0d - %0d %0d", counterY, video2ram.ram_addrY_reg, ram2video.ram_addrY_reg, (video2ram.ram_addrY_reg == ram2video.ram_addrY_reg), rdaddr);
        counterY <= counterY + 1;
      end else begin
        counterY <= 0;
      end
    end
  end

  `define __IsVerticalCaptureTime(y) ( \
      video2ram.line_doubler \
          ? (y < 240 || (y > 262 && y < video2ram.V_CAPTURE_END)) \
          : (y >= video2ram.V_CAPTURE_START && y < video2ram.V_CAPTURE_END) \
  )
  `define __IsCaptureTime(x,y) ( \
      `__IsVerticalCaptureTime(y) && x >= video2ram.H_CAPTURE_START && x < video2ram.H_CAPTURE_END \
  )

  initial 
    begin
      
      counterX <= 0;
      counterY <= 0;
      $monitor("%0d - %0d: %0dx%0d %0d(%0d) %0dx%0d %0d", $time, starttriggerOut, counterX, counterY, wraddr, wren, ram2video.counterX_reg, ram2video.counterY_reg, rdaddr);

      wait (starttriggerOut) begin
        $display("TRIGGER");
      end

      wait ((counterY >= 480 && ram2video.counterY_reg >= `VERTICAL_LINES_VISIBLE - `VERTICAL_OFFSET) || (wren && `IsDrawAreaVGA(ram2video.counterX_reg, ram2video.counterY_reg) && wraddr == rdaddr)) begin
        $display("stop: y:%0d ay:%0d ay2:%0d", counterY, wraddr, rdaddr);
        $finish;
      end
    end
endmodule
module I2C(
    // clock and reset
    input clk,
    input reset,

    // inputs
    input [6:0] chip_addr,
    input [7:0] reg_addr,
    input [7:0] value,
    input enable,
    input is_read,

    // I2C pins
    inout sda,
    inout scl,

    // outputs
    output reg [7:0] data,
    output reg done,
    output i2c_ack_error,
    input [31:0] divider
);

reg i2c_ena;
reg [6:0] i2c_addr;
reg i2c_rw;
reg [7:0] i2c_data_wr;
reg i2c_busy;
reg [7:0] i2c_data_rd;

i2c_master i2c_master(
    .clk       (clk),
    .reset_n   (1'b1),
    .ena       (i2c_ena),
    .addr      (i2c_addr),
    .rw        (i2c_rw),
    .data_wr   (i2c_data_wr),
    .busy      (i2c_busy),
    .data_rd   (i2c_data_rd),
    .ack_error (i2c_ack_error),
    .sda       (sda),
    .scl       (scl),
    .divider   (divider)
);

(* syn_encoding = "safe" *)
reg [1:0] state;
reg [5:0] busy_cnt;
reg busy_prev;

reg [6:0] chip_addr_reg;
reg [7:0] reg_addr_reg;
reg [7:0] value_reg;

localparam  s_idle = 0,
            s_send = 1;

initial begin
    state <= s_idle;
    busy_cnt = 0;
    done <= 1'b1;
end

always @ (posedge clk) begin
    if (~reset) begin
        state <= s_idle;
        busy_cnt = 0;
        done <= 1'b1;
    end
    else begin
        case(state)
            s_idle: begin
                if (enable) begin
                    chip_addr_reg <= chip_addr;
                    reg_addr_reg <= reg_addr;
                    value_reg <= value;
                    done <= 1'b0;
                    state <= s_send;
                end
            end
            
            s_send: begin
                busy_prev <= i2c_busy;
                if (~busy_prev && i2c_busy) begin
                    busy_cnt = busy_cnt + 1'b1;
                end
                case (busy_cnt)
                    0: begin
                        i2c_ena <= 1'b1;
                        i2c_addr <= chip_addr_reg;
                        i2c_rw <= 1'b0;
                        i2c_data_wr <= reg_addr_reg;
                    end
                    
                    1: begin
                        if (is_read) begin
                            i2c_rw <= 1'b1;
                        end else begin
                            i2c_data_wr <= value_reg;
                        end
                    end
                    
                    2: begin
                        i2c_ena <= 1'b0;
                        if (~i2c_busy) begin
                            data <= i2c_data_rd;
                            busy_cnt = 0;
                            done <= 1'b1;
                            state <= s_idle;
                        end
                    end
                endcase
            end
        endcase
    end
end

endmodule
module info_fifo (
	data,
	rdclk,
	rdreq,
	wrclk,
	wrreq,
	q,
	rdempty,
	wrfull);

	input	[23:0]  data;
	input	  rdclk;
	input	  rdreq;
	input	  wrclk;
	input	  wrreq;
	output	[23:0]  q;
	output	  rdempty;
	output	  wrfull;

	wire [23:0] sub_wire0;
	wire  sub_wire1;
	wire  sub_wire2;
	wire [23:0] q = sub_wire0[23:0];
	wire  rdempty = sub_wire1;
	wire  wrfull = sub_wire2;

	dcfifo	dcfifo_component (
				.data (data),
				.rdclk (rdclk),
				.rdreq (rdreq),
				.wrclk (wrclk),
				.wrreq (wrreq),
				.q (sub_wire0),
				.rdempty (sub_wire1),
				.wrfull (sub_wire2),
				.aclr (),
				.eccstatus (),
				.rdfull (),
				.rdusedw (),
				.wrempty (),
				.wrusedw ());
	defparam
		dcfifo_component.intended_device_family = "Cyclone 10 LP",
		dcfifo_component.lpm_numwords = 4,
		dcfifo_component.lpm_showahead = "OFF",
		dcfifo_component.lpm_type = "dcfifo",
		dcfifo_component.lpm_width = 24,
		dcfifo_component.lpm_widthu = 2,
		dcfifo_component.overflow_checking = "ON",
		dcfifo_component.rdsync_delaypipe = 5,
		dcfifo_component.underflow_checking = "ON",
		dcfifo_component.use_eab = "OFF",
		dcfifo_component.wrsync_delaypipe = 5;


endmodule
module data_cross(
    input clkIn,
    input clkOut,
    input [WIDTH-1:0] dataIn,
    output reg [WIDTH-1:0] dataOut
);
    parameter WIDTH = 8;
    
    reg wrreq = 0 /* synthesis noprune */;
    reg rdreq = 0 /* synthesis noprune */;
    reg wrfull /* synthesis noprune */;
    reg rdempty /* synthesis noprune */;
    reg [WIDTH-1:0] dataIn_reg = 0 /* synthesis noprune */;

    data_fifo #(
        .WIDTH(WIDTH)
    ) fifo (
        .wrclk(clkIn),
        .data(dataIn_reg),
        .wrreq(wrreq),
        .wrfull(wrfull),

        .rdclk(clkOut),
        .rdreq(rdreq),
        .rdempty(rdempty),
        .q(dataOut)
    );

    always @(posedge clkIn) begin
        dataIn_reg <= dataIn;
        if (dataIn_reg != dataIn) begin
            wrreq <= 1'b1;
        end else begin
            wrreq <= 1'b0;
        end
    end

    always @(posedge clkOut) begin
        if (~rdempty) begin
            rdreq <= 1'b1;
        end else begin
            rdreq <= 1'b0;
        end
    end

endmodule
module reconf_fifo (
	data,
	rdclk,
	rdreq,
	wrclk,
	wrreq,
	q,
	rdempty,
	wrfull);

	input	[7:0]  data;
	input	  rdclk;
	input	  rdreq;
	input	  wrclk;
	input	  wrreq;
	output	[7:0]  q;
	output	  rdempty;
	output	  wrfull;

	wire [7:0] sub_wire0;
	wire  sub_wire1;
	wire  sub_wire2;
	wire [7:0] q = sub_wire0[7:0];
	wire  rdempty = sub_wire1;
	wire  wrfull = sub_wire2;

	dcfifo	dcfifo_component (
				.data (data),
				.rdclk (rdclk),
				.rdreq (rdreq),
				.wrclk (wrclk),
				.wrreq (wrreq),
				.q (sub_wire0),
				.rdempty (sub_wire1),
				.wrfull (sub_wire2),
				.aclr (),
				.eccstatus (),
				.rdfull (),
				.rdusedw (),
				.wrempty (),
				.wrusedw ());
	defparam
		dcfifo_component.intended_device_family = "Cyclone 10 LP",
		dcfifo_component.lpm_numwords = 4,
		dcfifo_component.lpm_showahead = "OFF",
		dcfifo_component.lpm_type = "dcfifo",
		dcfifo_component.lpm_width = 8,
		dcfifo_component.lpm_widthu = 2,
		dcfifo_component.overflow_checking = "ON",
		dcfifo_component.rdsync_delaypipe = 5,
		dcfifo_component.underflow_checking = "ON",
		dcfifo_component.use_eab = "OFF",
		dcfifo_component.wrsync_delaypipe = 5;


endmodule
module data_fifo (
	data,
	rdclk,
	rdreq,
	wrclk,
	wrreq,
	q,
	rdempty,
	wrfull);

    parameter WIDTH = 24;

	input	[WIDTH-1:0]  data;
	input	  rdclk;
	input	  rdreq;
	input	  wrclk;
	input	  wrreq;
	output	[WIDTH-1:0]  q;
	output	  rdempty;
	output	  wrfull;

	wire [WIDTH-1:0] sub_wire0;
	wire  sub_wire1;
	wire  sub_wire2;
	wire [WIDTH-1:0] q = sub_wire0[WIDTH-1:0];
	wire  rdempty = sub_wire1;
	wire  wrfull = sub_wire2;

	dcfifo	dcfifo_component (
				.data (data),
				.rdclk (rdclk),
				.rdreq (rdreq),
				.wrclk (wrclk),
				.wrreq (wrreq),
				.q (sub_wire0),
				.rdempty (sub_wire1),
				.wrfull (sub_wire2),
				.aclr (),
				.eccstatus (),
				.rdfull (),
				.rdusedw (),
				.wrempty (),
				.wrusedw ());
	defparam
		dcfifo_component.intended_device_family = "Cyclone 10 LP",
		dcfifo_component.lpm_numwords = 4,
		dcfifo_component.lpm_showahead = "OFF",
		dcfifo_component.lpm_type = "dcfifo",
		dcfifo_component.lpm_width = WIDTH,
		dcfifo_component.lpm_widthu = 2,
		dcfifo_component.overflow_checking = "ON",
		dcfifo_component.rdsync_delaypipe = 5,
		dcfifo_component.underflow_checking = "ON",
		dcfifo_component.use_eab = "OFF",
		dcfifo_component.wrsync_delaypipe = 5;


endmodule
module gammaconv(
    input clock,
    
    input [4:0] gamma_config,

    input in_wren,
    input [`RAM_WIDTH-1:0] in_wraddr,
    input [7:0] in_red,
    input [7:0] in_green,
    input [7:0] in_blue,
    input in_starttrigger,

    output reg wren,
    output reg [`RAM_WIDTH-1:0] wraddr,
    output reg [23:0] wrdata,
    output reg starttrigger
);

    wire [7:0] red;
    wire [7:0] green;
    wire [7:0] blue;

    gamma r(
        .clock(clock),
        .gamma_config(gamma_config),
        .in(in_red),
        .out(red)
    );

    gamma g(
        .clock(clock),
        .gamma_config(gamma_config),
        .in(in_green),
        .out(green)
    );

    gamma b(
        .clock(clock),
        .gamma_config(gamma_config),
        .in(in_blue),
        .out(blue)
    );

    reg wren_q;
    reg [`RAM_WIDTH-1:0] wraddr_q;
    reg starttrigger_q;

    always @(posedge clock) begin
        { wren, wren_q } <= { wren_q, in_wren };
        { wraddr, wraddr_q } <= { wraddr_q, in_wraddr };
        { starttrigger, starttrigger_q } <= { starttrigger_q, in_starttrigger };
        wrdata <= { red, green, blue };
    end

endmodule
module gamma(
    input clock,
    input [4:0] gamma_config,
    input [7:0] in,
    output reg [7:0] out
);

    always @(posedge clock) begin
        case (gamma_config)
            `GAMMA_0_714290: begin
                case (in)
                    `include "config/gamma_0_714290.v"
                endcase
            end
            `GAMMA_0_769231: begin
                case (in)
                    `include "config/gamma_0_769231.v"
                endcase
            end
            `GAMMA_0_833330: begin
                case (in)
                    `include "config/gamma_0_833330.v"
                endcase
            end
            `GAMMA_0_909090: begin
                case (in)
                    `include "config/gamma_0_909090.v"
                endcase
            end
            `GAMMA_1_1: begin
                case (in)
                    `include "config/gamma_1_1.v"
                endcase
            end
            `GAMMA_1_2: begin
                case (in)
                    `include "config/gamma_1_2.v"
                endcase
            end
            `GAMMA_1_3: begin
                case (in)
                    `include "config/gamma_1_3.v"
                endcase
            end
            `GAMMA_1_4: begin
                case (in)
                    `include "config/gamma_1_4.v"
                endcase
            end
            default: out <= in;
        endcase
    end

endmodule
module alpha_calc(
    input clock,
    input [23:0] data,
    input [8:0] alpha,
    output reg [23:0] data_out
);
    function [7:0] trunc_rddata(
        input[15:0] value
    );
        trunc_rddata = value[15:8];
    endfunction

    reg [15:0] r_a, g_a, b_a;

    always @(posedge clock) begin
        r_a <= { 8'b0, data[23:16] } * alpha;
        g_a <= { 8'b0, data[15:8] } * alpha;
        b_a <= { 8'b0, data[7:0] } * alpha;

        data_out <= { trunc_rddata(r_a), trunc_rddata(g_a), trunc_rddata(b_a) };
    end
endmodule
module osc (
		output wire  clkout, // clkout.clk
		input  wire  oscena  // oscena.oscena
	);

	altera_int_osc int_osc_0 (
		.oscena (oscena), // oscena.oscena
		.clkout (clkout)  // clkout.clk
	);

endmodule
module  altera_int_osc
	( 
	clkout,
	oscena) /* synthesis synthesis_clearbox=1 */;
	output   clkout;
	input   oscena;

	wire  wire_sd1_clkout;

	cyclone10lp_oscillator   sd1
	( 
	.clkout(wire_sd1_clkout),
	.oscena(oscena));
	assign
		clkout = wire_sd1_clkout;
endmodule //altera_int_osc
module synch_2 #(parameter WIDTH = 1) (
    input  wire [WIDTH-1:0] i,      // input signal
    output reg  [WIDTH-1:0] o,      // synchronized output
    input  wire             clk,    // clock to synchronize on
    output wire             rise,   // one-cycle rising edge pulse
    output wire             fall    // one-cycle falling edge pulse
);

reg [WIDTH-1:0] stage_1;
reg [WIDTH-1:0] stage_2;
reg [WIDTH-1:0] stage_3;

assign rise = (WIDTH == 1) ? (o & ~stage_2) : 1'b0;
assign fall = (WIDTH == 1) ? (~o & stage_2) : 1'b0;
always @(posedge clk) 
   {stage_2, o, stage_1} <= {o, stage_1, i};
   
endmodule
module pin_ddio_clk (
	datain_h,
	datain_l,
	outclock,
	dataout);

	input	[0:0]  datain_h;
	input	[0:0]  datain_l;
	input	  outclock;
	output	[0:0]  dataout;

	wire [0:0] sub_wire0;
	wire [0:0] dataout = sub_wire0[0:0];

	altddio_out	ALTDDIO_OUT_component (
				.datain_h (datain_h),
				.datain_l (datain_l),
				.outclock (outclock),
				.dataout (sub_wire0),
				.aclr (1'b0),
				.aset (1'b0),
				.oe (1'b1),
				.oe_out (),
				.outclocken (1'b1),
				.sclr (1'b0),
				.sset (1'b0));
	defparam
		ALTDDIO_OUT_component.extend_oe_disable = "OFF",
		ALTDDIO_OUT_component.intended_device_family = "Cyclone V",
		ALTDDIO_OUT_component.invert_output = "OFF",
		ALTDDIO_OUT_component.lpm_hint = "UNUSED",
		ALTDDIO_OUT_component.lpm_type = "altddio_out",
		ALTDDIO_OUT_component.oe_reg = "UNREGISTERED",
		ALTDDIO_OUT_component.power_up_high = "OFF",
		ALTDDIO_OUT_component.width = 1;


endmodule
module  mf_pllbase_0002(

	// interface 'refclk'
	input wire refclk,

	// interface 'reset'
	input wire rst,

	// interface 'outclk0'
	output wire outclk_0,

	// interface 'outclk1'
	output wire outclk_1,

	// interface 'outclk2'
	output wire outclk_2,

	// interface 'outclk3'
	output wire outclk_3,

	// interface 'outclk4'
	output wire outclk_4,

	// interface 'locked'
	output wire locked
);

	altera_pll #(
		.fractional_vco_multiplier("true"),
		.reference_clock_frequency("74.25 MHz"),
		.operation_mode("normal"),
		.number_of_clocks(5),
		.output_clock_frequency0("7.158999 MHz"),
		.phase_shift0("0 ps"),
		.duty_cycle0(50),
		.output_clock_frequency1("7.158999 MHz"),
		.phase_shift1("34921 ps"),
		.duty_cycle1(50),
		.output_clock_frequency2("28.635997 MHz"),
		.phase_shift2("0 ps"),
		.duty_cycle2(50),
		.output_clock_frequency3("132.766896 MHz"),
		.phase_shift3("6590 ps"),
		.duty_cycle3(50),
		.output_clock_frequency4("132.766892 MHz"),
		.phase_shift4("5649 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_4, outclk_3, outclk_2, outclk_1, outclk_0}),
		.locked	(locked),
		.fboutclk	( ),
		.fbclk	(1'b0),
		.refclk	(refclk)
	);
endmodule
module iob_ram_sp
  #(
    parameter HEXFILE="none",
    parameter DATA_W=8,
    parameter ADDR_W=14
    )
   (
    input                     clk,
    input                     en, 
    input                     we, 
    input [(ADDR_W-1):0]      addr,
    output reg [(DATA_W-1):0] dout,
    input [(DATA_W-1):0]      din
    );

   //this allows ISE 14.7 to work; do not remove
   localparam mem_init_file_int = HEXFILE;

   // Declare the RAM
   reg [DATA_W-1:0] 	      ram[2**ADDR_W-1:0];

   // Initialize the RAM
   initial 
     if(mem_init_file_int != "none")
       $readmemh(mem_init_file_int, ram, 0, 2**ADDR_W - 1);

   // Operate the RAM
   always @ (posedge clk)
     if(en)
       if (we)
         ram[addr] <= din;
       else
         dout <= ram[addr];

endmodule
module iob_ram_sp_tb;
   
   // Inputs
   reg clk;
   reg en; // enable access to ram
   reg we; // write enable
   reg [`ADDR_W-1:0] addr;
   reg [`DATA_W-1:0] data_in;
   
   // Ouptuts
   reg [`DATA_W-1:0] data_out;

   integer           i, seq_ini;

   parameter clk_per = 10; // clk period = 10 timeticks

   initial begin
      // optional VCD
`ifdef VCD
      $dumpfile("uut.vcd");
      $dumpvars();
`endif
      
      // Initialize Inputs
      clk = 1;
      en = 0;
      we = 0;
      addr = 0;

      // Number from which to start the incremental sequence to write into the RAM
      seq_ini = 32;

      #clk_per;
      @(posedge clk) #1;
      en = 1;

      // Write to all RAM words
      @(posedge clk) #1;
      we = 1;

      for(i = 0; i < 2**`ADDR_W; i = i + 1) begin
         addr = i;
         data_in = i+seq_ini;
         @(posedge clk) #1;
      end

      @(posedge clk) #1;
      we = 0;

      // Read from all RAM words
      @(posedge clk) #1;
      for(i = 0; i < 2**`ADDR_W; i = i + 1) begin
         addr = i;
         @(posedge clk) #1;
         if(i+seq_ini != data_out) begin
            $display("ERROR: read error in data_out. \n \t i=%0d; data = %h when it should have been %0h", i, i+seq_ini, data_out);
            $finish;
         end
      end

      @(posedge clk) #1;
      en = 0;

      #clk_per;
      $display("%c[1;34m",27);
      $display("Test completed successfully.");
      $display("%c[0m",27);
      #(5*clk_per) $finish;

   end

   // Instantiate the Unit Under Test (UUT)
   iob_ram_sp
     #(
       .DATA_W(`DATA_W), 
       .ADDR_W(`ADDR_W)
       ) 
   uut 
     (
      .clk(clk), 
      .en(en),
      .we(we),
      .addr(addr),
      .din(data_in),
      .dout(data_out)
      );
   
   // system clock
   always #(clk_per/2) clk = ~clk; 

endmodule
module iob_ram_t2p_asym_tb;

   //determine W_ADDR_W and R_ADDR_W
   localparam W_DATA_W = `W_DATA_W;
   localparam R_DATA_W = `R_DATA_W;
   localparam MAXDATA_W = `IOB_MAX(W_DATA_W, R_DATA_W);
   localparam MINDATA_W = `IOB_MIN(W_DATA_W, R_DATA_W);
   localparam MAXADDR_W = `MAXADDR_W;
   localparam MINADDR_W = MAXADDR_W - $clog2(MAXDATA_W/MINDATA_W);
   localparam W_ADDR_W = W_DATA_W == MINDATA_W? MAXADDR_W: MINADDR_W;
   localparam R_ADDR_W = R_DATA_W == MINDATA_W? MAXADDR_W: MINADDR_W;
 
   //write port 
   reg w_clk = 0;
   reg w_en = 0;
   reg [`W_DATA_W-1:0] w_data;
   reg [W_ADDR_W-1:0] w_addr;
   //read port
   reg                 r_clk = 0;
   reg                 r_en = 0;
   wire [`R_DATA_W-1:0] r_data;
   reg [R_ADDR_W-1:0]  r_addr;


   // clocks
   localparam clk_per_w = 10; //ns
   always #(clk_per_w/2) w_clk = ~w_clk; 

   localparam clk_per_r = 13; //ns
   always #(clk_per_r/2) r_clk = ~r_clk;
   
   localparam seq_ini = 10;
   integer              i;

   reg [`W_DATA_W*2**W_ADDR_W-1:0] test_data;
   reg [`R_DATA_W-1:0]             r_data_expected;

   initial begin

      if(W_DATA_W > R_DATA_W)
        $display("W_DATA_W > R_DATA_W");
      else if (W_DATA_W < R_DATA_W)
        $display("W_DATA_W < R_DATA_W");
      else
        $display("W_DATA_W = R_DATA_W");

      $display("W_DATA_W=%d", W_DATA_W);
      $display("W_ADDR_W=%d", W_ADDR_W);      
      $display("R_DATA_W=%d", R_DATA_W);
      $display("R_ADDR_W=%d", R_ADDR_W);
      
      //compute the test data
      for (i=0; i < 2**W_ADDR_W; i=i+1)
        test_data[i*`W_DATA_W +: `W_DATA_W] = i+seq_ini;    
      
      // optional VCD
`ifdef VCD
      $dumpfile("uut.vcd");
      $dumpvars();
`endif
      repeat(4) @(posedge w_clk) #1;

      //write all the locations of RAM 
      w_en = 1; 
      for(i = 0; i < 2**W_ADDR_W; i = i + 1) begin
         w_addr = i;
         w_data = i+seq_ini;
         @(posedge w_clk) #1;
      end
      w_en = 0;

      @(posedge r_clk) #1;

      //read all the locations of RAM
      r_en = 1;
      for(i = 0 ; i < 2**R_ADDR_W; i = i + 1) begin
         r_addr = i;
         @(posedge r_clk) #1;
         //verify response
         r_data_expected = test_data[i*`R_DATA_W +: `R_DATA_W];
         if(r_data !== r_data_expected)
           $display("ERROR: read addr=%x, got %x, expected %x", r_addr, r_data, r_data_expected);
      end
      
      #(5*clk_per_w) $finish;
   end


   // instantiate the Unit Under Test (UUT)
   iob_ram_t2p_asym
     #(
       .W_DATA_W(W_DATA_W),
       .R_DATA_W(R_DATA_W),
       .ADDR_W(MAXADDR_W)
       )
   uut 
     (
      .w_clk(w_clk), 
      .w_en(w_en),
      .w_addr(w_addr),
      .w_data(w_data), 
      
      .r_clk(r_clk),
      .r_en(r_en), 
      .r_addr(r_addr),
      .r_data(r_data)
      );

   
endmodule
module iob_ram_dp_be
  #(
    parameter HEXFILE = "none",
    parameter ADDR_W = 10, // Addr Width in bits : 2*ADDR_W = RAM Depth
    parameter DATA_W = 32  // Data Width in bits
    )
   (
    input                    clk,

    // Port A
    input                    enA,
    input [DATA_W/8-1:0] weA,
    input [ADDR_W-1:0]   addrA,
    input [DATA_W-1:0]   dinA,
    output [DATA_W-1:0]  doutA,

    // Port B
    input                    enB,
    input [DATA_W/8-1:0] weB,
    input [ADDR_W-1:0]   addrB,
    input [DATA_W-1:0]   dinB,
    output [DATA_W-1 :0] doutB
    );

   localparam COL_W = 8;
   localparam NUM_COL = DATA_W/COL_W;

`ifdef IS_CYCLONEV
   localparam file_suffix = {"7","6","5","4","3","2","1","0"};

   genvar                    i;
   generate
      for (i=0; i < NUM_COL; i=i+1) begin: ram_col
         localparam mem_init_file_int = (HEXFILE != "none")? {HEXFILE, "_", file_suffix[8*(i+1)-1 -: 8], ".hex"}: "none";

         iob_ram_dp
             #(
               .HEXFILE(mem_init_file_int),
               .ADDR_W(ADDR_W),
               .DATA_W(COL_W)
               ) ram
           (
            .clk   (clk),

            .enA   (enA),
            .addrA (addrA),
            .dinA  (dinA[i*COL_W +: COL_W]),
            .weA   (weA[i]),
            .doutA (doutA[i*COL_W +: COL_W]),

            .enB   (enB),
            .addrB (addrB),
            .dinB  (dinB[i*COL_W +: COL_W]),
            .weB   (weB[i]),
            .doutB (doutB[i*COL_W +: COL_W])
            );
      end
   endgenerate
`else // !IS_CYCLONEV
   // this allow ISE 14.7 to work; do not remove
   localparam mem_init_file_int = {HEXFILE, ".hex"};

   // Core Memory
   reg [DATA_W-1:0]      ram_block[(2**ADDR_W)-1:0];

   // Initialize the RAM
   initial
     if(mem_init_file_int != "none.hex")
       $readmemh(mem_init_file_int, ram_block, 0, 2**ADDR_W - 1);

   // Port-A Operation
   reg [DATA_W-1:0]      doutA_int;
   integer                   i;
   always @(posedge clk) begin
      if (enA) begin
         for (i=0; i < NUM_COL; i=i+1) begin
            if (weA[i]) begin
               ram_block[addrA][i*COL_W +: COL_W] <= dinA[i*COL_W +: COL_W];
            end
         end
         doutA_int <= ram_block[addrA]; // Send Feedback
      end
   end

   assign doutA = doutA_int;

   // Port-B Operation
   reg [DATA_W-1:0]      doutB_int;
   integer                   j;
   always @(posedge clk) begin
      if (enB) begin
         for (j=0; j < NUM_COL; j=j+1) begin
            if (weB[j]) begin
               ram_block[addrB][j*COL_W +: COL_W] <= dinB[j*COL_W +: COL_W];
            end
         end
         doutB_int <= ram_block[addrB]; // Send Feedback
      end
   end

   assign doutB = doutB_int;
`endif

endmodule