dakies/OSS_Verilog huggingface dataset:
module testbench;

parameter PERIOD = 20;

reg         i_clk, i_rst_n;
reg  [9:0]  i_freq_step;
wire [3:0]  o_dac;

nco  nco_inst(.MAX10_CLK1_50 (i_clk), 
                .KEY ({i_rst_n, 1'b0}),
                .SW (i_freq_step), 
                .VGA_R (o_dac)
                );

initial begin
    i_clk = 0;
    forever #(PERIOD/2) i_clk = ~i_clk;
end

initial begin
    i_rst_n = 1'b0;
    i_freq_step = 10'd64;

    @(negedge i_clk) i_rst_n = 1'b1;

    repeat (15) begin
        repeat (500000) @(negedge i_clk);
        i_freq_step = i_freq_step + 50;
    end

    $finish;  
end
  
endmodule
module testbench;

parameter PERIOD = 20;

reg         i_clk, i_rst_n;
wire [3:0]  o_dac;

sin_gen  gen_inst(.MAX10_CLK1_50 (i_clk), 
                    .KEY ({i_rst_n, 1'b0}), 
                    .VGA_R (o_dac)
                    );

initial begin
    i_clk = 0;
    forever #(PERIOD/2) i_clk = ~i_clk;
end

initial begin
    i_rst_n = 1'b0;

    @(negedge i_clk) i_rst_n = 1;

    repeat (10000) @(negedge i_clk);

    $finish;  
end
  
endmodule
module sin_gen(MAX10_CLK1_50, KEY, VGA_R);

input           MAX10_CLK1_50;
input   [1:0]   KEY;
output  [3:0]   VGA_R;

reg     [3:0]   sin_table_rom[1023:0];
reg     [9:0]   phase;
reg     [3:0]   dac_data;

wire    sys_clk     = MAX10_CLK1_50;
wire    sys_rst_n   = KEY[1];

assign  VGA_R = dac_data;   

initial $readmemh("sin_table_4bit.hex", sin_table_rom);

always @(posedge sys_clk)
    dac_data <= sin_table_rom[phase];

always @(posedge sys_clk, negedge sys_rst_n) begin
    if(~sys_rst_n) begin
        phase <= 0;
    end else begin
        phase <= phase + 1'b1;
    end
end

endmodule
module logic_elements(SW, LEDR);

input   [9:0]   SW;
output  [9:0]   LEDR;

wire    [9:0]   y;
wire    [9:0]   x;

assign LEDR = y;
assign x = SW;

assign y[0] = ~x[0];

assign y[1] = x[0] & x[1];

assign y[2] = ~(x[0] & x[1]);

assign y[3] = x[0] | x[1];

assign y[4] = ~(x[0] | x[1]);

assign y[5] = x[0] ^ x[1];

assign y[9:6] = 4'b1010;

endmodule
module dec_7seg(i_dat, o_seg);

input       [3:0]   i_dat;
output  reg [6:0]   o_seg;

always @* begin

    case (i_dat)

        4'h0: o_seg = 7'b1000000;
        4'h1: o_seg = 7'b1111001;
        4'h2: o_seg = 7'b0100100;
        4'h3: o_seg = 7'b0110000;
        4'h4: o_seg = 7'b0011001;
        4'h5: o_seg = 7'b0010010;
        4'h6: o_seg = 7'b0000010;
        4'h7: o_seg = 7'b1111000;
        4'h8: o_seg = 7'b0000000;
        4'h9: o_seg = 7'b0011000;
        4'hA: o_seg = 7'b0001000;
        4'hB: o_seg = 7'b0000011;
        4'hC: o_seg = 7'b1000110;
        4'hD: o_seg = 7'b0100001;
        4'hE: o_seg = 7'b0000110;
        4'hF: o_seg = 7'b0001110;

    endcase

end


endmodule
module debouncer(i_clk, i_button, o_buttton);

parameter CNT_WIDTH = 16;

input   i_clk;
input   i_button;
output  o_buttton;

reg                 but_sync1_ff = 1'b0;
reg                 but_sync2_ff = 1'b0;

reg [CNT_WIDTH-1:0] cnt = 0;
wire                cnt_full = &cnt;

reg                 but_state;
wire                but_new_state = but_sync2_ff;
wire                but_state_dif = but_state ^ but_new_state;

assign o_buttton = but_state;

always @(posedge i_clk)
    but_sync1_ff <= i_button;

always @(posedge i_clk)
    but_sync2_ff <= but_sync1_ff;
    
always @(posedge i_clk)
    if (cnt_full)
        but_state <= ~but_state;
    
always @(posedge i_clk) begin
    if (but_state_dif) begin
        cnt <= cnt + 1'b1;
    end else begin
        cnt <= 0;
    end
end   

endmodule
module shift_reg (KEY, SW, LEDR);

input   [1:0]   KEY;
input   [9:0]   SW;
output  [9:0]   LEDR;

wire            clk = KEY[0];
wire            rst_n = KEY[1];

reg     [9:0]   shift_reg;

assign LEDR = shift_reg;
                                        
always @(posedge clk, negedge rst_n)

    if (~rst_n) begin
        shift_reg <= 0;
    end else begin
        shift_reg <= {shift_reg[8:0], SW[0]};    
    end
    
endmodule
module lfsr10bit(KEY, SW, LEDR);

input   [1:0]   KEY;
input   [9:0]   SW;
output  [9:0]   LEDR;

reg     [9:0]   lfsr;

wire            clk = KEY[0];
wire            rst_n = KEY[1];

wire    lfsr_lsb = ~(lfsr[9] ^ lfsr[6]);

assign LEDR = lfsr;

always @(posedge clk, negedge rst_n) begin
    if (~rst_n) begin
        lfsr <= 0;
    end else begin
        lfsr <= {lfsr[8:0], lfsr_lsb};
    end
end

endmodule
module simple_spi(MAX10_CLK1_50, GPIO, KEY, LEDR);

input           MAX10_CLK1_50;
input   [35:0]  GPIO;
input   [1:0]   KEY;
output  [9:0]   LEDR;

wire    sys_clk     = MAX10_CLK1_50;
wire    sys_rst_n   = KEY[1];

wire    spi_sck     = GPIO[0];
wire    spi_cs      = GPIO[1];
wire    spi_mosi    = GPIO[2];

wire    sck_rs_edg;
wire    tr_cmplt;

reg     [7:0]   user_reg_ff;
reg     [7:0]   spi_dat_ff;

reg     [2:0]   sck_sync_ff;
reg     [2:0]   cs_sync_ff;
reg     [1:0]   mosi_sync_ff;   

assign LEDR = user_reg_ff;

assign    sck_rs_edg    = ~sck_sync_ff[2] & sck_sync_ff[1];
assign    tr_cmplt      = ~cs_sync_ff[2] & cs_sync_ff[1];

// you should obligatorily implement reset on all control lines
always @(posedge sys_clk, negedge sys_rst_n) begin
    if (~sys_rst_n) begin
        sck_sync_ff <= 3'b000;
    end else begin
        sck_sync_ff <= {sck_sync_ff[1:0], spi_sck};
    end
end 
    
always @(posedge sys_clk, negedge sys_rst_n) begin
    if (~sys_rst_n) begin
        cs_sync_ff <= 3'b111;
    end else begin
        cs_sync_ff <= {cs_sync_ff[1:0], spi_cs};
    end    
end    

// it is not necessary implement reset on data lines
// but you can do it if you want
always @(posedge sys_clk)
    mosi_sync_ff <= {mosi_sync_ff[0], spi_mosi}; 

always @(posedge sys_clk) begin
    if (sck_rs_edg)
        spi_dat_ff <= {spi_dat_ff[6:0], mosi_sync_ff[1]};
end

always @(posedge sys_clk)
    if (tr_cmplt)
        user_reg_ff <= spi_dat_ff;
        
endmodule
module dec_7seg_tb;

parameter DELAY = 20;

reg     [3:0]   bin_code;
wire    [6:0]   segments;

dec_7seg    dec_7seg_inst(.i_dat (bin_code), 
                          .o_seg (segments)
                          );

integer unsigned i;

initial begin

    for (i = 0; i < 16; i = i + 1) begin
        bin_code = i;
        #DELAY;
    end

    $finish;

end

endmodule
module dec_7seg(i_dat, o_seg);

input       [3:0]   i_dat;
output  reg [6:0]   o_seg;

always @* begin

    case (i_dat)

        4'h0: o_seg = 7'b1000000;
        4'h1: o_seg = 7'b1111001;
        4'h2: o_seg = 7'b0100100;
        4'h3: o_seg = 7'b0110000;
        4'h4: o_seg = 7'b0011001;
        4'h5: o_seg = 7'b0010010;
        4'h6: o_seg = 7'b0000010;
        4'h7: o_seg = 7'b1111000;
        4'h8: o_seg = 7'b0000000;
        4'h9: o_seg = 7'b0011000;
        4'hA: o_seg = 7'b0001000;
        4'hB: o_seg = 7'b0000011;
        4'hC: o_seg = 7'b1000110;
        4'hD: o_seg = 7'b0100001;
        4'hE: o_seg = 7'b0000110;
        4'hF: o_seg = 7'b0001110;

    endcase

end

endmodule
module dec_7seg_demo (SW, HEX0);

input   [9:0]   SW;
output  [7:0]   HEX0;  

dec_7seg    dec_7seg_inst(.i_dat (SW[3:0]), 
                          .o_seg (HEX0)
                          );


endmodule
module counter(i_clk, i_rst_n, i_srst, i_cnt_en, o_tick, o_data);

parameter MAX_VAL = 7;
parameter WIDTH   = 4;

input               i_clk;
input               i_rst_n;
input               i_srst;
input               i_cnt_en;
output  [WIDTH-1:0] o_data;
output  reg         o_tick;

reg     [WIDTH-1:0] cnt;

wire    cnt_overflow = ((MAX_VAL == cnt) & i_cnt_en);

assign  o_data = cnt;

always @(posedge i_clk, negedge i_rst_n) begin
    if(~i_rst_n) begin
        o_tick <= 1'b0;
    end else begin
        if (cnt_overflow)
            o_tick <= 1'b1;
        else
            o_tick <= 1'b0;
    end
end

always @(posedge i_clk, negedge i_rst_n) begin
    if(~i_rst_n) begin
        cnt <= 0;
    end else begin
        if (cnt_overflow | i_srst)
            cnt <= 0;
        else if (i_cnt_en)
            cnt <= cnt + 1'b1;
    end
end

endmodule
module clock_tb;

parameter PERIOD = 20;
parameter DELAY_CYCLES = 60*60*24*10;

reg         i_clk;
reg         i_rst_n;

wire [6:0]  hex0, hex1, hex2, hex3, hex4, hex5;

clock #(.DIV_CONST(10) ) clock_inst(.MAX10_CLK1_50 (i_clk), 
                                 .KEY ({i_rst_n, 1'b0}), 
                                 .HEX0 (hex0),
                                 .HEX1 (hex1),
                                 .HEX2 (hex2),
                                 .HEX3 (hex3),
                                 .HEX4 (hex4),
                                 .HEX5 (hex5)
                                );

initial begin
    i_clk = 0;
    forever #(PERIOD/2) i_clk = ~i_clk;
end

initial begin

    i_rst_n = 1'b0;

    @(negedge i_clk) i_rst_n = 1'b1;

    repeat (DELAY_CYCLES) @(negedge i_clk);

    $finish;

end

endmodule
module const_div(i_clk, i_rst_n, o_clk);

input           i_clk;
input           i_rst_n;
output          o_clk;

parameter       DIV_BY = 7;
localparam      N = $clog2(DIV_BY);

reg     [N-1:0] cnt;

wire    [N-1:0] cnt_max      = (DIV_BY-1);
wire            sync_rst_cnt = (cnt_max== cnt);

assign o_clk = sync_rst_cnt;

always @(posedge i_clk, negedge i_rst_n) begin
    if(~i_rst_n) begin
        cnt <= 0;
    end else begin
        if (sync_rst_cnt)
            cnt <= 0;
        else
            cnt <= cnt + 1'b1;
    end
end

endmodule
module dec_7seg_demo (MAX10_CLK1_50, KEY, HEX0);

input           MAX10_CLK1_50;
input   [1:0]   KEY;
output  [7:0]   HEX0;

parameter DIV_CONST = 50_000_000;

wire    sys_clk     = MAX10_CLK1_50;
wire    sys_rst_n   = KEY[1]; 

wire    tick_event;

reg     [3:0]   cnt;

dec_7seg    dec_7seg_inst(.i_dat (cnt), 
                          .o_seg (HEX0)
                          );

const_div #(.DIV_BY(DIV_CONST)) div_inst(.i_clk (sys_clk), 
                                         .i_rst_n (sys_rst_n), 
                                         .o_clk (tick_event)
                                        );

always @(posedge sys_clk, negedge sys_rst_n) begin

    if (~sys_rst_n) begin

        cnt <= 4'd0;

    end else begin

        if (tick_event)
            cnt <= cnt + 1'b1;

    end

end

endmodule
module dec_7seg_demo_tb;

parameter PERIOD = 20;
parameter DELAY_CYCLES = 16*50_000_000;

reg         i_clk;
reg         i_rst_n;

wire [6:0]  o_seg;

dec_7seg_demo dec_7seg_demo_inst(.MAX10_CLK1_50 (i_clk), 
                                 .KEY ({i_rst_n, 1'b0}), 
                                 .HEX0 (o_seg)
                                );

initial begin
    i_clk = 0;
    forever #(PERIOD/2) i_clk = ~i_clk;
end

initial begin

    i_rst_n = 1'b0;

    @(negedge i_clk) i_rst_n = 1'b1;

    repeat (DELAY_CYCLES) @(negedge i_clk);

    $finish;

end

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

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

endmodule
module adc_fifo (
	aclr,
	data,
	rdclk,
	rdreq,
	wrclk,
	wrreq,
	q,
	rdempty,
	wrfull,
	wrusedw);

	input	  aclr;
	input	[11:0]  data;
	input	  rdclk;
	input	  rdreq;
	input	  wrclk;
	input	  wrreq;
	output	[11:0]  q;
	output	  rdempty;
	output	  wrfull;
	output	[9:0]  wrusedw;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri0	  aclr;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

	wire [11:0] sub_wire0;
	wire  sub_wire1;
	wire  sub_wire2;
	wire [9:0] sub_wire3;
	wire [11:0] q = sub_wire0[11:0];
	wire  rdempty = sub_wire1;
	wire  wrfull = sub_wire2;
	wire [9:0] wrusedw = sub_wire3[9:0];

	dcfifo	dcfifo_component (
				.aclr (aclr),
				.data (data),
				.rdclk (rdclk),
				.rdreq (rdreq),
				.wrclk (wrclk),
				.wrreq (wrreq),
				.q (sub_wire0),
				.rdempty (sub_wire1),
				.wrfull (sub_wire2),
				.wrusedw (sub_wire3),
				.eccstatus (),
				.rdfull (),
				.rdusedw (),
				.wrempty ());
	defparam
		dcfifo_component.add_usedw_msb_bit = "ON",
		dcfifo_component.intended_device_family = "Cyclone V",
		dcfifo_component.lpm_numwords = 512,
		dcfifo_component.lpm_showahead = "ON",
		dcfifo_component.lpm_type = "dcfifo",
		dcfifo_component.lpm_width = 12,
		dcfifo_component.lpm_widthu = 10,
		dcfifo_component.overflow_checking = "ON",
		dcfifo_component.rdsync_delaypipe = 5,
		dcfifo_component.read_aclr_synch = "OFF",
		dcfifo_component.underflow_checking = "ON",
		dcfifo_component.use_eab = "ON",
		dcfifo_component.write_aclr_synch = "OFF",
		dcfifo_component.wrsync_delaypipe = 5;


endmodule
module top(CLOCK_50, KEY, LEDR, ADC_CONVST, ADC_SCLK, ADC_DIN, ADC_DOUT, GPIO_0);

input           CLOCK_50;

input   [1:0]   KEY;

output  [9:0]   LEDR;

output  [35:0]  GPIO_0;

output          ADC_CONVST;
output          ADC_SCLK;
input           ADC_DOUT;
output          ADC_DIN;

wire            pll_locked;

wire            sys_rst_n = KEY[1];
wire            sys_clk;            // 100 MHz
wire            adc_clk;            // 40 MHz

wire    [11:0]  fifo_in_data;
wire    [11:0]  fifo_out_data;

wire            fifo_full;
wire            fifo_empty;

wire            fifo_write_req;
reg             fifo_read_ack = 1'b0;

reg             adc_data_valid = 1'b0;
reg     [11:0]  adc_data;
wire            adc_measure_done;
reg             adc_measure_done_ff = 1'b0;

reg     [7:0]   tick_cnt          = 8'd0;

reg     [3:0]   pll_locked_ff     = 4'b0000;

assign          LEDR[0]           = pll_locked;
assign          GPIO_0[11:0]      = adc_data;
assign          GPIO_0[12]        = adc_data_valid;

assign          fifo_write_req    = ~adc_measure_done_ff & adc_measure_done & ~fifo_full; 

system_pll sys_pll ( .refclk (CLOCK_50),
                     .rst (~sys_rst_n),
                     .outclk_0 (sys_clk),
                     .outclk_1 (adc_clk),
                     .locked (pll_locked)
	               );
                   
adc_ltc2308 adc (.i_clk (adc_clk),
	             .i_rst_n (pll_locked_ff[3]), // posedge triggle
	             .i_measure_ch (3'd0),
	             .o_measure_done (adc_measure_done),
	             .o_measure_data (fifo_in_data),
	
	             // adc interface
	             .ADC_CONVST (ADC_CONVST),
	             .ADC_SCK (ADC_SCLK),
	             .ADC_SDI (ADC_DIN),
	             .ADC_SDO (ADC_DOUT)
                 );
                 
adc_fifo adc_fifo_inst( .aclr(~sys_rst_n),
                        .data (fifo_in_data),
                        .rdclk (sys_clk),
                        .rdreq (fifo_read_ack),
                        .wrclk (adc_clk),
                        .wrreq (fifo_write_req),
                        .q (fifo_out_data),
                        .rdempty (fifo_empty),
                        .wrfull (fifo_full)
                       );
                       
always @(posedge adc_clk, negedge sys_rst_n)
    if (~sys_rst_n)
        adc_measure_done_ff <= 1'b0;
    else
        adc_measure_done_ff <= adc_measure_done;    

always @(posedge adc_clk, negedge sys_rst_n)
    if (~sys_rst_n)
        pll_locked_ff <= 4'b0000;
    else
        pll_locked_ff <= {pll_locked_ff[2:0], pll_locked}; 

always @(posedge sys_clk, negedge sys_rst_n)
    if (~sys_rst_n) begin
        tick_cnt       <= 8'd0;
        fifo_read_ack  <= 1'b0;
        adc_data       <= 12'd0;
        adc_data_valid <= 1'b0;
    end else begin
        tick_cnt       <= tick_cnt + 1'b1;
        fifo_read_ack  <= 1'b0;
        adc_data_valid <= 1'b0;
        
        if (8'd199 == tick_cnt) begin
            tick_cnt       <= 8'd0;
            adc_data_valid <= ~fifo_empty;
            fifo_read_ack  <= ~fifo_empty;
            adc_data       <= fifo_out_data - 12'd2048;
        end
        
    end 
        
endmodule
module  system_pll_0002(

	// interface 'refclk'
	input wire refclk,

	// interface 'reset'
	input wire rst,

	// interface 'outclk0'
	output wire outclk_0,

	// interface 'outclk1'
	output wire outclk_1,

	// interface 'locked'
	output wire locked
);

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

input           MAX10_CLK1_50;
input   [1:0]   KEY;
output  [35:0]  GPIO;

parameter   N = 7;

reg     [N-1:0] one_hot_cnt;

wire    sys_clk     = MAX10_CLK1_50;
wire    sys_rst_n   = KEY[1];

assign GPIO[0] = one_hot_cnt[0];

always @(posedge sys_clk, negedge sys_rst_n) begin
    if(~sys_rst_n) begin
        one_hot_cnt <= 1;
    end else begin
        one_hot_cnt <= {one_hot_cnt[N-2:0], one_hot_cnt[N-1]};
    end
end


endmodule
module testbench;

parameter PERIOD = 20;
parameter DIV_BY = 7;

reg         i_clk, i_rst_n;
wire        o_clk;
wire [35:0] gpio;

one_hot_div #(.N(DIV_BY)) oh_div_inst(.MAX10_CLK1_50(i_clk), 
                                        .KEY ({i_rst_n, 1'b0}), 
                                        .GPIO (gpio)
                                    );

assign o_clk = gpio[0];

initial begin
    i_clk = 0;
    forever #(PERIOD/2) i_clk = ~i_clk;
end

initial begin
    i_rst_n = 1'b0;

    @(negedge i_clk) i_rst_n = 1;

    repeat (20) @(negedge i_clk);

    $finish;  
end
  
endmodule
module testbench;

parameter PERIOD = 20;
parameter DIV_BY = 7;

wire [35:0] gpio;        
wire        o_clk;
reg         i_clk, i_rst_n;
reg [9:0]   i_div_by;

integer i = 0;

prog_div prog_div_inst(.MAX10_CLK1_50(i_clk), 
                        .KEY ({i_rst_n, 1'b0}),
                        .SW (i_div_by), 
                        .GPIO (gpio)
                        );

assign o_clk = gpio[0];

initial begin
    i_clk = 0;
    forever #(PERIOD/2) i_clk = ~i_clk;
end

initial begin
    i_rst_n = 1'b0;
    i_div_by = 0;

    @(negedge i_clk) i_rst_n = 1;

    repeat(10) @(negedge i_clk);

    for (i=1; i<1024; i=i+1) begin   
        i_div_by = i;         
        repeat(5*i) @(negedge i_clk);
    end

    $finish;  
end
  
endmodule
module prog_div(MAX10_CLK1_50, KEY, SW, GPIO);

input           MAX10_CLK1_50;
input   [1:0]   KEY;
input   [9:0]   SW;
output  [35:0]  GPIO;

reg     [9:0]   cnt_ff;
reg     [9:0]   div_const_ff;

wire    sys_clk     = MAX10_CLK1_50;
wire    sys_rst_n   = KEY[1];
wire    preload_cnt = ~|cnt_ff;

assign GPIO[0] = preload_cnt;

always @(posedge sys_clk, negedge sys_rst_n) begin
    if(~sys_rst_n) begin
        div_const_ff <= 1;
    end else begin
        div_const_ff <= SW; //for simplicity here we don't use synchronization
    end
end

always @(posedge sys_clk, negedge sys_rst_n) begin
    if(~sys_rst_n) begin
        cnt_ff <= 0;
    end else begin
        if (preload_cnt)
            cnt_ff <= div_const_ff;
        else
            cnt_ff <= cnt_ff - 1'b1;
    end
end

endmodule
module simple_uart_receiver(i_clk, i_rst_n, i_rx, o_dat, o_dat_vld);

input           i_clk;
input           i_rst_n;
input           i_rx;
output  reg     o_dat_vld;
output  [7:0]   o_dat;

parameter       RCONST = 1085; //230400bps for 250MHz i_clk

reg     [10:0]  baud_rate_cnt;
reg     [3:0]   bit_cnt;
reg     [7:0]   shift_reg;
reg     [1:0]   rx_sync;
reg     [7:0]   data_reg;

assign o_dat = data_reg;

always @(posedge i_clk)
    if ( (9 == bit_cnt) && (RCONST/2 == baud_rate_cnt) ) begin
        data_reg    <= shift_reg;
        o_dat_vld   <= 1'b1;
    end else begin
        o_dat_vld   <= 1'b0;
    end

always @(posedge i_clk)
    rx_sync <= {rx_sync[0], i_rx};

always @(posedge i_clk)
    if( RCONST/2 == baud_rate_cnt )
        shift_reg <= {rx_sync[1], shift_reg[7:1]};

always @(posedge i_clk, negedge i_rst_n)
    if (~i_rst_n) begin
        baud_rate_cnt <= 0;
    end else begin
        if ( (RCONST == baud_rate_cnt) || (10 == bit_cnt) )
            baud_rate_cnt <= 0;
        else
            baud_rate_cnt <= baud_rate_cnt + 1'b1;
    end

always @(posedge i_clk, negedge i_rst_n)
    if (~i_rst_n) begin
        bit_cnt <= 0;
    end else begin
        if ( (10 == bit_cnt) && (1'b0 == rx_sync[1]) )
            bit_cnt <= 0;
        else if (RCONST == baud_rate_cnt)
            bit_cnt <= bit_cnt + 1'b1;
    end

endmodule
module fm_transmitter(MAX10_CLK1_50, GPIO, KEY, LEDR);

input           MAX10_CLK1_50;
inout   [35:0]  GPIO;
input   [1:0]   KEY;
output  [9:0]   LEDR;

parameter   NCO_PHASE_STEP_CARRIER = 32'h5C28_F5C2; // 90 MHz FM carrier, 250 MHz sys_clk

wire    sys_rst_n = KEY[0];
wire    sys_clk;

wire    [7:0]   uart_dat;
reg     [7:0]   sample;

reg     [31:0]  nco_phase;
reg     [31:0]  nco_phase_step;
wire    [31:0]  nco_phase_step_carrier = NCO_PHASE_STEP_CARRIER;
wire    [31:0]  nco_phase_step_deviation = { {(32-8-13){sample[7]}}, sample, 13'b0 };

mypll pll_inst(.inclk0 (MAX10_CLK1_50),
                .c0 (sys_clk), // 250 MHz clock
                .locked (LEDR[0])
                );
    
simple_uart_receiver uart_rec(.i_clk (sys_clk), 
                                .i_rst_n (sys_rst_n), 
                                .i_rx (GPIO[0]), 
                                .o_dat (uart_dat), 
                                .o_dat_vld ()
                                );
                               
always @(posedge sys_clk)
    sample <= uart_dat - 128;
    
always @(posedge sys_clk)
    nco_phase_step <= nco_phase_step_carrier + nco_phase_step_deviation;
    
always @(posedge sys_clk)
    nco_phase <= nco_phase + nco_phase_step;

assign GPIO[35] = nco_phase[31];
                                
endmodule
module const_div(MAX10_CLK1_50, KEY, GPIO);

input           MAX10_CLK1_50;
input   [1:0]   KEY;
output  [35:0]  GPIO;

parameter       DIV_BY = 7;
localparam      N = $clog2(DIV_BY);

reg     [N-1:0] cnt;

wire    sys_clk         = MAX10_CLK1_50;
wire    sys_rst_n       = KEY[1];
wire    sync_rst_cnt    = (DIV_BY-1) == cnt;

assign GPIO[0] = sync_rst_cnt;

always @(posedge sys_clk, negedge sys_rst_n) begin
    if(~sys_rst_n) begin
        cnt <= 0;
    end else begin
        if (sync_rst_cnt)
            cnt <= 0;
        else
            cnt <= cnt + 1'b1;
    end
end


endmodule
module testbench;

parameter PERIOD = 20;
parameter DIV_BY = 7;

reg         i_clk, i_rst_n;
wire        o_clk;
wire [35:0] gpio;

const_div #(.DIV_BY(DIV_BY)) const_div_inst(.MAX10_CLK1_50(i_clk), 
                                            .KEY ({i_rst_n, 1'b0}), 
                                            .GPIO (gpio)
                                            );

assign o_clk = gpio[0];

initial begin
    i_clk = 0;
    forever #(PERIOD/2) i_clk = ~i_clk;
end

initial begin
    i_rst_n = 1'b0;

    @(negedge i_clk) i_rst_n = 1;

    repeat (30) @(negedge i_clk);

    $finish;  
end
  
endmodule
module const_div(MAX10_CLK1_50, KEY, GPIO);

input           MAX10_CLK1_50;
input   [1:0]   KEY;
output  [35:0]  GPIO;

parameter       DIV_BY      = 7;
localparam      CNT_CONST   = DIV_BY - 1;
localparam      N           = $clog2(DIV_BY);

reg     [N-1:0] cnt;

wire    sys_clk     = MAX10_CLK1_50;
wire    sys_rst_n   = KEY[1];
wire    preload_cnt = ~|cnt;

assign GPIO[0] = preload_cnt;

always @(posedge sys_clk, negedge sys_rst_n) begin
    if(~sys_rst_n) begin
        cnt <= CNT_CONST;
    end else begin
        if (preload_cnt)
            cnt <= CNT_CONST;
        else
            cnt <= cnt - 1'b1;
    end
end


endmodule
module simple_pwm (MAX10_CLK1_50, KEY, SW, GPIO);

input           MAX10_CLK1_50;
input   [1:0]   KEY;
input   [9:0]   SW;
inout   [35:0]  GPIO;

wire            sys_clk = MAX10_CLK1_50;

reg     [9:0]   cnt_ff  = 0;
reg     [9:0]   dc_ff   = 0;
reg             out_ff  = 1'b1;
reg             en_ff   = 1'b1;

always @(posedge sys_clk) begin
    en_ff <= KEY[0];
    dc_ff <= SW;
end

always @(posedge sys_clk)
    if(en_ff)
        cnt_ff <= cnt_ff + 1'b1;

always @(posedge sys_clk)
    out_ff <= (cnt_ff < dc_ff);

assign GPIO[0] = out_ff;

endmodule
module audio_pcm_pwm (MAX10_CLK1_50, GPIO, KEY, LEDR);

input           MAX10_CLK1_50;
inout   [35:0]  GPIO;
input   [1:0]   KEY;
output  [9:0]   LEDR;

wire            sys_clk;
wire            sys_rst_n = KEY[0];

reg             pwm_out_ff;
reg     [7:0]   pwm_cnt_ff;
reg     [7:0]   pcm_sample_ff;
wire    [7:0]   uart_dat;

mypll pll_inst(.inclk0 (MAX10_CLK1_50),
                .c0 (sys_clk),          // 255 MHz clock
                .locked (LEDR[0])
                );

simple_uart_receiver uart_rec(.i_clk (sys_clk), 
                                .i_rst_n (sys_rst_n), 
                                .i_rx (GPIO[0]), 
                                .o_dat (uart_dat), 
                                .o_dat_vld ()
                                );

always @(posedge sys_clk)
    pcm_sample_ff <= uart_dat;

always @(posedge sys_clk)
    pwm_cnt_ff <= pwm_cnt_ff + 1'b1;

always @(posedge sys_clk)
    pwm_out_ff <= (pwm_cnt_ff < pcm_sample_ff);

assign GPIO[35] = pwm_out_ff;

endmodule
module simple_uart_receiver(i_clk, i_rst_n, i_rx, o_dat, o_dat_vld);

input           i_clk;
input           i_rst_n;
input           i_rx;
output  reg     o_dat_vld;
output  [7:0]   o_dat;

parameter       RCONST = 1107; //230400bps for 255MHz i_clk

reg     [10:0]  baud_rate_cnt;
reg     [3:0]   bit_cnt;
reg     [7:0]   shift_reg;
reg     [1:0]   rx_sync;
reg     [7:0]   data_reg;

assign o_dat = data_reg;

always @(posedge i_clk)
    if ( (9 == bit_cnt) && (RCONST/2 == baud_rate_cnt) ) begin
        data_reg    <= shift_reg;
        o_dat_vld   <= 1'b1;
    end else begin
        o_dat_vld   <= 1'b0;
    end

always @(posedge i_clk)
    rx_sync <= {rx_sync[0], i_rx};

always @(posedge i_clk)
    if( RCONST/2 == baud_rate_cnt )
        shift_reg <= {rx_sync[1], shift_reg[7:1]};

always @(posedge i_clk, negedge i_rst_n)
    if (~i_rst_n) begin
        baud_rate_cnt <= 0;
    end else begin
        if ( (RCONST == baud_rate_cnt) || (10 == bit_cnt) )
            baud_rate_cnt <= 0;
        else
            baud_rate_cnt <= baud_rate_cnt + 1'b1;
    end

always @(posedge i_clk, negedge i_rst_n)
    if (~i_rst_n) begin
        bit_cnt <= 0;
    end else begin
        if ( (10 == bit_cnt) && (1'b0 == rx_sync[1]) )
            bit_cnt <= 0;
        else if (RCONST == baud_rate_cnt)
            bit_cnt <= bit_cnt + 1'b1;
    end

endmodule
module pwm_am_transmitter (MAX10_CLK1_50, GPIO, KEY, LEDR);

input           MAX10_CLK1_50;
inout   [35:0]  GPIO;
input   [1:0]   KEY;
output  [9:0]   LEDR;

wire    [7:0]   uart_dat;
reg     [9:0]   pcm_sample_ff;

reg             pwm_out_ff;
reg     [9:0]   pwm_cnt_ff;

wire    sys_rst_n = KEY[0];
wire    sys_clk;

mypll pll_inst(.inclk0 (MAX10_CLK1_50),
                .c0 (sys_clk),        // 250 MHz clock
                .locked (LEDR[0])
                );
    
simple_uart_receiver uart_rec(.i_clk (sys_clk), 
                                .i_rst_n (sys_rst_n), 
                                .i_rx (GPIO[0]), 
                                .o_dat (uart_dat), 
                                .o_dat_vld ()
                                );
always @(posedge sys_clk)
    pcm_sample_ff <= {uart_dat, 1'b0};
          
always @(posedge sys_clk)
    pwm_cnt_ff <= pwm_cnt_ff + 1'b1;
    
always @(posedge sys_clk)
    pwm_out_ff <= (pwm_cnt_ff < pcm_sample_ff);

assign GPIO[35] = pwm_out_ff;     
          
endmodule
module pwm_control_period (i_clk, i_period, i_duty_cyle, o_pwm);

parameter PWM_WIDTH = 10;

input                   i_clk;
input   [PWM_WIDTH-1:0] i_period;       // max val for pwm counter
input   [PWM_WIDTH-1:0] i_duty_cyle;    // i_duty_cyle should be less or equal then i_period
output                  o_pwm;

reg     [PWM_WIDTH-1:0] cnt_ff  = 0;
reg     [PWM_WIDTH-1:0] duty_cyle_ff = 0;
reg     [PWM_WIDTH-1:0] period_ff = 0;
reg                     out_ff  = 1'b0;

always @(posedge i_clk) begin
    period_ff    <= i_period;
    duty_cyle_ff <= i_duty_cyle;
end

always @(posedge i_clk)
    if(cnt_ff == period_ff)
        cnt_ff <= 0;
    else 
        cnt_ff <= cnt_ff + 1'b1;

always @(posedge i_clk)
    out_ff <= (cnt_ff < duty_cyle_ff);

assign o_pwm = out_ff;

endmodule
module testbench;

parameter PERIOD = 20;
parameter PWM_WIDTH = 10;

wire                o_pwm;
reg                 i_clk;
reg [PWM_WIDTH-1:0] i_period;       // max val for pwm counter
reg [PWM_WIDTH-1:0] i_duty_cyle;    // i_duty_cyle should be less or equal then i_period

integer i = 0;
integer j = 0;

pwm_control_period #(.PWM_WIDTH(PWM_WIDTH)) pwm_inst(.i_clk (i_clk), 
                                                    .i_period (i_period), 
                                                    .i_duty_cyle (i_duty_cyle), 
                                                    .o_pwm (o_pwm)
                                                    );

initial begin
    i_clk = 0;
    forever #(PERIOD/2) i_clk = ~i_clk;
end

initial begin
    i_duty_cyle = 0;
    i_period = 0;

    repeat(10) @(negedge i_clk);

    for (j=PWM_WIDTH/2; j<=PWM_WIDTH; j=j+1) begin

        i_period = (1'b1<<j) - 1'b1;
        @(negedge i_clk);
        
        for (i=0; i<=i_period; i=i+1) begin   
            i_duty_cyle = i;      
            repeat (5*(i_period + 1)) @(negedge i_clk);
        end

    end

    $finish;  
end
  
endmodule
module priority_encoder_DE10_Lite (SW, HEX0, LEDR);

input   [9:0]   SW;
output  [9:0]   LEDR;
output  [6:0]   HEX0;

wire    [2:0]   bin;

priority_encoder #(.ONEHOT_WIDTH(8)) enc_inst(.i_one_hot (SW[7:0]), 
                                               .o_bin (bin),
                                               .o_active (LEDR[0])
                                              );

dec_7seg    ind_hex0(.i_dat ({1'b0, bin}), 
                     .o_seg (HEX0)
                    );

endmodule
module testbench;

parameter DELAY = 20;

reg     [15:0]  one_hot;
wire    [3:0]   bin;
wire            active;

priority_encoder #(.ONEHOT_WIDTH(16)) enc_inst(.i_one_hot (one_hot), 
                                                .o_bin (bin),
                                                .o_active (active)
                                                );

initial begin
    
    one_hot = 16'b0;
    #DELAY;

    one_hot = 16'b1;

    repeat (15) begin
        #DELAY;
        one_hot = one_hot << 1;
    end

    repeat (100) begin
        #DELAY;
        one_hot = $random;
    end

    $finish;

end

endmodule
module priority_encoder (i_one_hot, o_bin, o_active);

parameter ONEHOT_WIDTH = 16;
parameter BIN_WIDTH = $clog2(ONEHOT_WIDTH);

input       [ONEHOT_WIDTH-1:0]  i_one_hot;
output reg  [BIN_WIDTH-1:0]     o_bin;
output                          o_active;

integer i = 0;

assign o_active = |i_one_hot;

always @* begin

    o_bin = 0;

    for (i=0; i<ONEHOT_WIDTH; i=i+1)
        if (i_one_hot[i])
            o_bin = i;

end

endmodule
module barrel_shifter_right (i_data, i_sa, i_st, o_data);

parameter DATA_WIDTH = 10;
parameter SA_WIDTH = $clog2(DATA_WIDTH);

input                     i_st;    // st - shift type (0:logical 1:arithmetic)
input   [DATA_WIDTH-1:0]  i_data;
input   [SA_WIDTH-1:0]    i_sa;    // sa -shift amount
output  [DATA_WIDTH-1:0]  o_data;

reg     [DATA_WIDTH-1:0]  shift_result;

always @* begin
    shift_result = $signed({ (i_st & i_data[DATA_WIDTH-1]) , i_data}) >>> i_sa;
end

assign o_data = shift_result;

endmodule
module barrel_shifter_DE10_Lite (KEY, SW, LEDR);

input   [1:0]   KEY;
input   [9:0]   SW;
output  [9:0]   LEDR;

barrel_shifter_right #(.DATA_WIDTH (8)) bsr_inst(.i_data (SW[7:0]), 
                                                 .i_sa ({~KEY[0], SW[9:8]}), 
                                                 .i_st (KEY[1]), 
                                                 .o_data (LEDR[7:0])
                                                 );

endmodule
module testbench;

parameter DATA_WIDTH = 16;
parameter SA_WIDTH = $clog2(DATA_WIDTH);
parameter DELAY = 20;
parameter N = 10_000;

reg                     i_st;    // st - shift type (0:logical 1:arithmetic)
reg   [DATA_WIDTH-1:0]  i_data;
reg   [SA_WIDTH-1:0]    i_sa;    // sa -shift amount
wire  [DATA_WIDTH-1:0]  o_data;

barrel_shifter_right #(.DATA_WIDTH (DATA_WIDTH)) bsr_inst(.i_data (i_data), 
                                                           .i_sa (i_sa), 
                                                           .i_st (i_st), 
                                                           .o_data (o_data)
                                                           );
initial begin

    repeat (N) begin
        i_st    = $random;
        i_sa    = $random;
        i_data  = $random;
        #DELAY;
    end

    $finish;

end

endmodule
module testbench;

parameter DELAY = 20;

reg     [7:0] one_hot;
wire    [2:0] bin;
wire          active;

enc8in enc_inst(.i_one_hot (one_hot), 
                .o_bin (bin),
                .o_active (active)
                );

initial begin
    
    one_hot = 8'b0;
    #DELAY;

    one_hot = 8'b1;

    repeat (7) begin
        #DELAY;
        one_hot = one_hot << 1;
    end

    repeat (30) begin
        #DELAY;
        one_hot = $random;
    end

    $finish;

end

endmodule
module enc8in (i_one_hot, o_bin, o_active);

input       [7:0] i_one_hot;
output reg  [2:0] o_bin;
output reg        o_active;

always @* begin
    o_bin[0] = i_one_hot[1] | i_one_hot[3] | i_one_hot[5] | i_one_hot[7];
    o_bin[1] = i_one_hot[2] | i_one_hot[3] | i_one_hot[6] | i_one_hot[7];
    o_bin[2] = i_one_hot[4] | i_one_hot[5] | i_one_hot[6] | i_one_hot[7];
    o_active = |i_one_hot;
end

endmodule
module encoder_DE10_Lite (SW, HEX0, LEDR);

input   [9:0]   SW;
output  [9:0]   LEDR;
output  [6:0]   HEX0;

wire    [2:0]   bin;

enc8in enc_inst(.i_one_hot (SW[7:0]), 
                .o_bin (bin),
                .o_active (LEDR[0])
                );

dec_7seg    ind_hex0(.i_dat ({1'b0, bin}), 
                     .o_seg (HEX0)
                    );

endmodule
module barrel_shifter_right (i_data, i_sa, i_st, o_data);

input          i_st;    // st - shift type (0:logical 1:arithmetic)
input   [7:0]  i_data;
input   [2:0]  i_sa;    // sa -shift amount
output  [7:0]  o_data;

wire    [7:0]  mux0_to_mux1;
wire    [7:0]  mux1_to_mux2;

mux_2in1_type2 #(.WIDTH(8)) mux0(.i_dat0 (i_data), 
                                 .i_dat1 ({i_st & i_data[7], i_data[7:1]}), 
                                 .i_sel (i_sa[0]), 
                                 .o_dat (mux0_to_mux1)
                                 );

mux_2in1_type2 #(.WIDTH(8)) mux1(.i_dat0 (mux0_to_mux1), 
                                 .i_dat1 ({ {2{i_st & mux0_to_mux1[7]}}, mux0_to_mux1[7:2]}), 
                                 .i_sel (i_sa[1]), 
                                 .o_dat (mux1_to_mux2)
                                 );

mux_2in1_type2 #(.WIDTH(8)) mux2(.i_dat0 (mux1_to_mux2), 
                                 .i_dat1 ({ {4{i_st & mux1_to_mux2[7]}}, mux1_to_mux2[7:4]}), 
                                 .i_sel (i_sa[2]), 
                                 .o_dat (o_data)
                                 );

endmodule
module barrel_shifter_DE10_Lite (KEY, SW, LEDR);

input   [1:0]   KEY;
input   [9:0]   SW;
output  [9:0]   LEDR;

barrel_shifter_right bsr_inst(.i_data (SW[7:0]), 
                              .i_sa ({~KEY[0], SW[9:8]}), 
                              .i_st (KEY[1]), 
                              .o_data (LEDR[7:0])
                              );

endmodule
module mux_2in1_type2 (i_dat0, i_dat1, i_sel, o_dat);

parameter WIDTH = 8;

input                    i_sel;
input       [WIDTH-1:0]  i_dat0;
input       [WIDTH-1:0]  i_dat1;
output reg  [WIDTH-1:0]  o_dat;

always @* begin
    if (i_sel)
        o_dat = i_dat1;
    else
        o_dat = i_dat0;
end

endmodule
module testbench;

parameter DELAY = 20;
parameter N = 10_000;

reg          i_st;    // st - shift type (0:logical 1:arithmetic)
reg   [7:0]  i_data;
reg   [2:0]  i_sa;    // sa -shift amount
wire  [7:0]  o_data;

barrel_shifter_right  bsr_inst(.i_data (i_data), 
                               .i_sa (i_sa), 
                               .i_st (i_st), 
                               .o_data (o_data)
                              );
initial begin

    repeat (N) begin
        i_st    = $random;
        i_sa    = $random;
        i_data  = $random;
        #DELAY;
    end

    $finish;

end

endmodule
module mux_2in1_type1 (i_dat0, i_dat1, i_sel, o_dat);

parameter WIDTH = 8;

input                i_sel;
input   [WIDTH-1:0]  i_dat0;
input   [WIDTH-1:0]  i_dat1;
output  [WIDTH-1:0]  o_dat;

assign  o_dat = i_sel ? i_dat1 : i_dat0;

endmodule
module bin8_to_bcd_DE10_Lite (SW, HEX0, HEX1, HEX2);

input   [9:0]   SW;
output  [6:0]   HEX0, HEX1, HEX2;

wire    [11:0]  bcd;

bin8_to_bcd bin2bcd_inst (.i_bin (SW[7:0]), 
                          .o_bcd (bcd)
                          );

dec_7seg    bcd0(.i_dat (bcd[3:0]), 
                 .o_seg (HEX0)
                 );

dec_7seg    bcd1(.i_dat (bcd[7:4]), 
                 .o_seg (HEX1)
                 );

dec_7seg    bcd2(.i_dat (bcd[11:8]), 
                 .o_seg (HEX2)
                 );

endmodule
module testbench;

parameter DELAY = 20;

reg   [7:0]   bin;
wire  [11:0]  bcd;

integer i;

bin8_to_bcd bin2bcd_inst (.i_bin (bin), 
                          .o_bcd (bcd)
                          );

initial begin
    
    for (i=0; i<256; i=i+1) begin
        bin = i;
        #DELAY;
    end

    $finish;

end

endmodule
module bin8_to_bcd (i_bin, o_bcd);

input       [7:0]   i_bin;
output reg  [11:0]  o_bcd;

integer i;   
     
always @* begin

    o_bcd = 0;

    for (i = 0; i < 8; i = i+1) begin

        o_bcd = {o_bcd[10:0], i_bin[7-i]};              

        if(i < 7 && o_bcd[3:0] > 4) 
            o_bcd[3:0] = o_bcd[3:0] + 3;

        if(i < 7 && o_bcd[7:4] > 4)
            o_bcd[7:4] = o_bcd[7:4] + 3;

        if(i < 7 && o_bcd[11:8] > 4)
            o_bcd[11:8] = o_bcd[11:8] + 3;  

    end

end     

endmodule
module testbench;

parameter DELAY = 20;

reg     [15:0]  one_hot;
wire    [3:0]   bin;
wire            active;

enc_param #(.ONEHOT_WIDTH(16)) enc_inst(.i_one_hot (one_hot), 
                                        .o_bin (bin),
                                        .o_active (active)
                                        );

initial begin
    
    one_hot = 16'b0;
    #DELAY;

    one_hot = 16'b1;

    repeat (15) begin
        #DELAY;
        one_hot = one_hot << 1;
    end

    repeat (60) begin
        #DELAY;
        one_hot = $random;
    end

    $finish;

end

endmodule
module enc_param (i_one_hot, o_bin, o_active);

parameter ONEHOT_WIDTH = 16;
parameter BIN_WIDTH = $clog2(ONEHOT_WIDTH);

input   [ONEHOT_WIDTH-1:0]  i_one_hot;
output  [BIN_WIDTH-1:0]     o_bin;
output                      o_active;

genvar i,j;

assign o_active = |i_one_hot;

generate
	for (j=0; j<BIN_WIDTH; j=j+1)
	begin : jl
		wire [ONEHOT_WIDTH-1:0] tmp_mask;
		for (i=0; i<ONEHOT_WIDTH; i=i+1)
		begin : il
			assign tmp_mask[i] = i[j];
		end
		assign o_bin[j] = |(tmp_mask & i_one_hot);
	end
endgenerate

endmodule
module encoder_DE10_Lite (SW, HEX0, LEDR);

input   [9:0]   SW;
output  [9:0]   LEDR;
output  [6:0]   HEX0;

wire    [2:0]   bin;

enc_param #(.ONEHOT_WIDTH(8)) enc_inst(.i_one_hot (SW[7:0]), 
                                       .o_bin (bin),
                                       .o_active (LEDR[0])
                                      );

dec_7seg    ind_hex0(.i_dat ({1'b0, bin}), 
                     .o_seg (HEX0)
                    );

endmodule
module testbench;

parameter DELAY = 20;
parameter DEC_OUT_NUM = 17;

reg     [$clog2(DEC_OUT_NUM)-1:0]   bin;
wire    [DEC_OUT_NUM-1:0]           one_hot;

integer i;

decoder #(.ONE_HOT_WIDTH(DEC_OUT_NUM)) dec_inst(.i_bin (bin), 
                                                .o_one_hot (one_hot)
                                               );

initial begin

    for (i=0; i<DEC_OUT_NUM; i=i+1) begin
        bin = i;
        #DELAY;
    end

    $finish;

end


endmodule
module decoder (i_bin, o_one_hot);

parameter ONE_HOT_WIDTH = 8;
parameter BIN_WIDTH = $clog2(ONE_HOT_WIDTH);

input       [BIN_WIDTH-1:0]     i_bin;
output reg  [ONE_HOT_WIDTH-1:0] o_one_hot;

always @* begin
    o_one_hot = 0;
    o_one_hot[i_bin] = 1'b1;
end

endmodule
module decoder_DE10_Lite (SW, LEDR);

input   [9:0]   SW;
output  [9:0]   LEDR;

decoder #(.ONE_HOT_WIDTH(10)) dec_inst(.i_bin (SW[3:0]), 
                                       .o_one_hot (LEDR)
                                       );

endmodule
module testbench;

parameter DELAY = 20;
parameter WIDTH = 8;

reg     [WIDTH-1:0]  i_dat0, i_dat1, i_dat2, i_dat3, i_dat4;
reg     [2:0]        i_sel;
wire    [WIDTH-1:0]  o_dat;

integer i;

mux_5in1 #(.WIDTH(WIDTH)) mux_inst(.i_dat0 (i_dat0), 
                                   .i_dat1 (i_dat1), 
                                   .i_dat2 (i_dat2), 
                                   .i_dat3 (i_dat3), 
                                   .i_dat4 (i_dat4), 
                                   .i_sel (i_sel), 
                                   .o_dat (o_dat)
                                   );

initial begin
    
    for (i=0; i<8; i=i+1) begin

        i_sel = i;

        repeat (10) begin
            i_dat0 = $random;
            i_dat1 = $random;
            i_dat2 = $random;
            i_dat3 = $random;
            i_dat4 = $random;
            #DELAY;
        end

    end

    $finish;

end

endmodule
module mux_5in1 (i_dat0, i_dat1, i_dat2, i_dat3, i_dat4, i_sel, o_dat);

parameter WIDTH = 8;

input       [2:0]        i_sel;
input       [WIDTH-1:0]  i_dat0, i_dat1, i_dat2, i_dat3, i_dat4;
output reg  [WIDTH-1:0]  o_dat;

always @* begin

    o_dat = 0;

    case (i_sel)

    3'd0: o_dat = i_dat0;

    3'd1: o_dat = i_dat1;

    3'd2: o_dat = i_dat2;

    3'd3: o_dat = i_dat3;

    3'd4: o_dat = i_dat4;

    endcase

end

endmodule
module test_bench(

    );
	
	reg rst;
	reg clk;
	wire [7:0] ans;
	wire [6:0] seg;
	wire [9:0] led;
	initial
	begin 
		clk = 1'b0;
		rst = 1'b1;
		#500;
		rst = 1'b0;
	end
	always #10 clk = ~clk;
	top top(
		.hclk(clk),
		.rst(rst),
		.seg(seg),
	    .ans(ans),
	    .led(led)
		);
endmodule
module testbench();
	reg clk;
	reg rst;

	wire[31:0] writedata,dataadr;
	wire memwrite;

	top dut(clk,rst,writedata,dataadr,memwrite);

	initial begin 
		rst <= 1;
		#200;
		rst <= 0;
	end

	always begin
		clk <= 1;
		#10;
		clk <= 0;
		#10;
	
	end

	always @(negedge clk) begin
		if(memwrite) begin
			/* code */
			if(dataadr === 84 & writedata === 7) begin
				/* code */
				$display("Simulation succeeded");
				$stop;
			end else if(dataadr !== 80) begin
				/* code */
				$display("Simulation Failed");
				$stop;
			end
		end
	end
endmodule
module Rom(
    input [15:0] ins,
    input clk,
    input reset,
    output [6:0] seg,
    output [7:0] ans
    );
    wire [31:0] InsData;
    Ins_ROM Ins_Rom(.clka(clk),         // input wire clka
            .addra({{16{ins[15]}},ins[15:0]}),     // input wire [15 : 0] addra
            .douta(InsData[31:0])         // output wire [31 : 0] douta
    );
    display display_0(.clk(clk),.reset(reset),.s(InsData),.ans(ans),.seg(seg));
            
endmodule
module seg7(
    input wire [3:0]din,
    output reg [6:0]dout
    );
 
    always@(*)
    case(din)
        5'h0:dout = 7'b000_0001;
        5'h1:dout = 7'b100_1111;
        5'h2:dout = 7'b001_0010;
        5'h3:dout = 7'b000_0110;
        5'h4:dout = 7'b100_1100;
        5'h5:dout = 7'b010_0100;
        5'h6:dout = 7'b010_0000;
        5'h7:dout = 7'b000_1111;
        5'h8:dout = 7'b000_0000;
        5'h9:dout = 7'b000_0100;
        5'ha:dout = 7'b000_1000;
        5'hb:dout = 7'b110_0000;
        5'hc:dout = 7'b011_0001;
        5'hd:dout = 7'b100_0010;
        5'he:dout = 7'b011_0000;
        5'hf:dout = 7'b011_1000;
        default:dout = 7'b111_1111;        
    endcase
    
    
endmodule
module display(
    input wire clk,reset,
    input wire [31:0]s,
    output wire [6:0]seg,
    output reg [7:0]ans
    );
    reg [20:0]count;
    reg [4:0]digit; 
    always@(posedge clk,posedge reset)
    if(reset)  
        count = 0;
    else 
        count = count + 1;
       
    always @(posedge clk)
    case(count[20:18])
        0:begin
            ans = 8'b11111110;
            digit = s[3:0];
        end
        
        1:begin
            ans = 8'b11111101;
            digit = s[7:4];
        end

        2:begin
            ans = 8'b11111011;
            digit =s[11:8];
        end
        
        3:begin
            ans = 8'b11110111;
            digit = s[15:12];
        end
        
         4:begin
             ans = 8'b11101111;
             digit = s[19:16];
         end
               
         5:begin
             ans = 8'b11011111;
             digit = s[23:20];
         end
       
         6:begin
             ans = 8'b10111111;
             digit =s[27:24];
         end
               
         7:begin
             ans = 8'b01111111;
             digit = s[31:28];
         end
    endcase
    
    seg7 U4(.din(digit),.dout(seg));
endmodule
module adder(
	input wire[31:0] a,b,
	output wire[31:0] y
    );

	assign y = a + b;
endmodule
module floprc #(parameter WIDTH = 8)(
	input wire clk,rst,clear,
	input wire[WIDTH-1:0] d,
	output reg[WIDTH-1:0] q
    );

	always @(posedge clk,posedge rst) begin
		if(rst) begin
			q <= 0;
		end else if (clear)begin
			q <= 0;
		end else begin 
			q <= d;
		end
	end
endmodule
module mux2 #(parameter WIDTH = 8)(
	input wire[WIDTH-1:0] d0,d1,
	input wire s,
	output wire[WIDTH-1:0] y
    );
	
	assign y = s ? d1 : d0;
endmodule
module signext(
	input wire[15:0] a,
	output wire[31:0] y
    );

	assign y = {{16{a[15]}},a};
endmodule
module flopenr #(parameter WIDTH = 8)(
	input wire clk,rst,en,
	input wire[WIDTH-1:0] d,
	output reg[WIDTH-1:0] q
    );
	always @(posedge clk) begin
		if(rst) begin
			q <= 0;
		end else if(en) begin
			/* code */
			q <= d;
		end
	end
endmodule
module controller(
	input wire clk,rst,
	//decode stage
	input wire[5:0] opD,functD,
	output wire pcsrcD,branchD,equalD,jumpD,
	
	//execute stage
	input wire flushE,
	output wire memtoregE,alusrcE,
	output wire regdstE,regwriteE,	
	output wire[2:0] alucontrolE,

	//mem stage
	output wire memtoregM,memwriteM,
				regwriteM,
	//write back stage
	output wire memtoregW,regwriteW

    );
	
	//decode stage
	wire[1:0] aluopD;
	wire memtoregD,memwriteD,alusrcD,
		regdstD,regwriteD;
	wire[2:0] alucontrolD;

	//execute stage
	wire memwriteE;

	maindec md(
		opD,
		memtoregD,memwriteD,
		branchD,alusrcD,
		regdstD,regwriteD,
		jumpD,
		aluopD
		);
	aludec ad(functD,aluopD,alucontrolD);

	assign pcsrcD = branchD & equalD;

	//pipeline registers
	floprc #(8) regE(
		clk,
		rst,
		flushE,
		{memtoregD,memwriteD,alusrcD,regdstD,regwriteD,alucontrolD},
		{memtoregE,memwriteE,alusrcE,regdstE,regwriteE,alucontrolE}
		);
	flopr #(8) regM(
		clk,rst,
		{memtoregE,memwriteE,regwriteE},
		{memtoregM,memwriteM,regwriteM}
		);
	flopr #(8) regW(
		clk,rst,
		{memtoregM,regwriteM},
		{memtoregW,regwriteW}
		);
endmodule