dakies/OSS_Verilog huggingface dataset:
module LoopyGen(input clk, input ce,
                input is_rendering,
                input [2:0] ain,   // input address from CPU
                input [7:0] din,   // data input
                input read,        // read
                input write,       // write
                input is_pre_render, // Is this the pre-render scanline
                input [8:0] cycle,
                output [14:0] loopy,
                output [2:0] fine_x_scroll);  // Current loopy value
  // Controls how much to increment on each write
  reg ppu_incr; // 0 = 1, 1 = 32
  // Current VRAM address
  reg [14:0] loopy_v;
  // Temporary VRAM address
  reg [14:0] loopy_t;
  // Fine X scroll (3 bits)
  reg [2:0] loopy_x;
  // Latch
  reg ppu_address_latch;
  initial begin
    ppu_incr = 0;
    loopy_v = 0;
    loopy_t = 0;
    loopy_x = 0;
    ppu_address_latch = 0;
  end
  // Handle updating loopy_t and loopy_v
  always @(posedge clk) if (ce) begin
    if (is_rendering) begin
      // Increment course X scroll right after attribute table byte was fetched.
      if (cycle[2:0] == 3 && (cycle < 256 || cycle >= 320 && cycle < 336)) begin
        loopy_v[4:0] <= loopy_v[4:0] + 1;
        loopy_v[10] <= loopy_v[10] ^ (loopy_v[4:0] == 31);
      end

      // Vertical Increment
      if (cycle == 251) begin
        loopy_v[14:12] <= loopy_v[14:12] + 1;
        if (loopy_v[14:12] == 7) begin
          if (loopy_v[9:5] == 29) begin
            loopy_v[9:5] <= 0;
            loopy_v[11] <= !loopy_v[11];
          end else begin
            loopy_v[9:5] <= loopy_v[9:5] + 1;
          end
        end
      end

      // Horizontal Reset at cycle 257
      if (cycle == 256)
        {loopy_v[10], loopy_v[4:0]} <= {loopy_t[10], loopy_t[4:0]};

      // On cycle 256 of each scanline, copy horizontal bits from loopy_t into loopy_v
      // On cycle 304 of the pre-render scanline, copy loopy_t into loopy_v
      if (cycle == 304 && is_pre_render) begin
        loopy_v <= loopy_t;
      end
    end
    if (write && ain == 0) begin
      loopy_t[10] <= din[0];
      loopy_t[11] <= din[1];
      ppu_incr <= din[2];
    end else if (write && ain == 5) begin
      if (!ppu_address_latch) begin
        loopy_t[4:0] <= din[7:3];
        loopy_x <= din[2:0];
      end else begin
        loopy_t[9:5] <= din[7:3];
        loopy_t[14:12] <= din[2:0];
      end
      ppu_address_latch <= !ppu_address_latch;
    end else if (write && ain == 6) begin
      if (!ppu_address_latch) begin
        loopy_t[13:8] <= din[5:0];
        loopy_t[14] <= 0;
      end else begin
        loopy_t[7:0] <= din;
        loopy_v <= {loopy_t[14:8], din};
      end
      ppu_address_latch <= !ppu_address_latch;
    end else if (read && ain == 2) begin
      ppu_address_latch <= 0; //Reset PPU address latch
    end else if ((read || write) && ain == 7 && !is_rendering) begin
      // Increment address every time we accessed a reg
      loopy_v <= loopy_v + (ppu_incr ? 32 : 1);
    end
  end
  assign loopy = loopy_v;
  assign fine_x_scroll = loopy_x;
endmodule
module ClockGen(input clk, input ce, input reset,
                input is_rendering,
                output reg [8:0] scanline,
                output reg [8:0] cycle,
                output reg is_in_vblank,
                output end_of_line,
                output at_last_cycle_group,
                output exiting_vblank,
                output entering_vblank,
                output reg is_pre_render);
  reg second_frame;

  // Scanline 0..239 = picture scan lines
  // Scanline 240 = dummy scan line
  // Scanline 241..260 = VBLANK
  // Scanline -1 = Pre render scanline (Fetches objects for next line)
  assign at_last_cycle_group = (cycle[8:3] == 42);
  // Every second pre-render frame is only 340 cycles instead of 341.
  assign end_of_line = at_last_cycle_group && cycle[3:0] == (is_pre_render && second_frame && is_rendering ? 3 : 4);
  // Set the clock right before vblank begins
  assign entering_vblank = end_of_line && scanline == 240;
  // Set the clock right before vblank ends
  assign exiting_vblank = end_of_line && scanline == 260;
  // New value for is_in_vblank flag
  wire new_is_in_vblank = entering_vblank ? 1'b1 : exiting_vblank ? 1'b0 : is_in_vblank;
  // Set if the current line is line 0..239
  always @(posedge clk) if (reset) begin
    cycle <= 0;
    is_in_vblank <= 1;
  end else if (ce) begin
    cycle <= end_of_line ? 0 : cycle + 1;
    is_in_vblank <= new_is_in_vblank;
  end
//  always @(posedge clk) if (ce) begin
//    $write("%x %x %x %x %x\n", new_is_in_vblank, entering_vblank, exiting_vblank, is_in_vblank, entering_vblank ? 1'b1 : exiting_vblank ? 1'b0 : is_in_vblank);

//  end
  always @(posedge clk) if (reset) begin
    scanline <= 0;
    is_pre_render <= 0;
    second_frame <= 0;
  end else if (ce && end_of_line) begin
    // Once the scanline counter reaches end of 260, it gets reset to -1.
    scanline <= exiting_vblank ? 9'b111111111 : scanline + 1;
    // The pre render flag is set while we're on scanline -1.
    is_pre_render <= exiting_vblank;

    if (exiting_vblank)
      second_frame <= !second_frame;
  end

endmodule // ClockGen
module Sprite(input clk, input ce,
              input enable,
              input [3:0] load,
              input [26:0] load_in,
              output [26:0] load_out,
              output [4:0] bits); // Low 4 bits = pixel, high bit = prio
  reg [1:0] upper_color; // Upper 2 bits of color
  reg [7:0] x_coord;     // X coordinate where we want things
  reg [7:0] pix1, pix2;  // Shift registers, output when x_coord == 0
  reg aprio;             // Current prio
  wire active = (x_coord == 0);
  always @(posedge clk) if (ce) begin
    if (enable) begin
      if (!active) begin
        // Decrease until x_coord is zero.
        x_coord <= x_coord - 8'h01;
      end else begin
        pix1 <= pix1 >> 1;
        pix2 <= pix2 >> 1;
      end
    end
    if (load[3]) pix1 <= load_in[26:19];
    if (load[2]) pix2 <= load_in[18:11];
    if (load[1]) x_coord <= load_in[10:3];
    if (load[0]) {upper_color, aprio} <= load_in[2:0];
  end
  assign bits = {aprio, upper_color, active && pix2[0], active && pix1[0]};
  assign load_out = {pix1, pix2, x_coord, upper_color, aprio};
endmodule  // SpriteGen
module SpriteSet(input clk, input ce,   // Input clock
                 input enable,          // Enable pixel generation
                 input [3:0] load,      // Which parts of the state to load/shift.
                 input [26:0] load_in,  // State to load with
                 output [4:0] bits,     // Output bits
                 output is_sprite0);    // Set to true if sprite #0 was output

  wire [26:0] load_out7, load_out6, load_out5, load_out4, load_out3, load_out2, load_out1, load_out0;
  wire [4:0] bits7, bits6, bits5, bits4, bits3, bits2, bits1, bits0;
  Sprite sprite7(clk, ce, enable, load, load_in,   load_out7, bits7);
  Sprite sprite6(clk, ce, enable, load, load_out7, load_out6, bits6);
  Sprite sprite5(clk, ce, enable, load, load_out6, load_out5, bits5);
  Sprite sprite4(clk, ce, enable, load, load_out5, load_out4, bits4);
  Sprite sprite3(clk, ce, enable, load, load_out4, load_out3, bits3);
  Sprite sprite2(clk, ce, enable, load, load_out3, load_out2, bits2);
  Sprite sprite1(clk, ce, enable, load, load_out2, load_out1, bits1);
  Sprite sprite0(clk, ce, enable, load, load_out1, load_out0, bits0);
  // Determine which sprite is visible on this pixel.
  assign bits = bits0[1:0] != 0 ? bits0 :
                bits1[1:0] != 0 ? bits1 :
                bits2[1:0] != 0 ? bits2 :
                bits3[1:0] != 0 ? bits3 :
                bits4[1:0] != 0 ? bits4 :
                bits5[1:0] != 0 ? bits5 :
                bits6[1:0] != 0 ? bits6 :
                                  bits7;
  assign is_sprite0 = bits0[1:0] != 0;
endmodule  // SpriteSet
module BgPainter(input clk, input ce,
                 input enable,             // Shift registers activated
                 input [2:0] cycle,
                 input [2:0] fine_x_scroll,
                 input [14:0] loopy,
                 output [7:0] name_table,  // VRAM name table to read next.
                 input [7:0] vram_data,
                 output [3:0] pixel);
  reg [15:0] playfield_pipe_1; // Name table pixel pipeline #1
  reg [15:0] playfield_pipe_2; // Name table pixel pipeline #2
  reg [8:0]  playfield_pipe_3; // Attribute table pixel pipe #1
  reg [8:0]  playfield_pipe_4; // Attribute table pixel pipe #2
  reg [7:0] current_name_table;      // Holds the current name table byte
  reg [1:0] current_attribute_table; // Holds the 2 current attribute table bits
  reg [7:0] bg0;                // Pixel data for last loaded background
  wire [7:0] bg1 =  vram_data;
  initial begin
    playfield_pipe_1 = 0;
    playfield_pipe_2 = 0;
    playfield_pipe_3 = 0;
    playfield_pipe_4 = 0;
    current_name_table = 0;
    current_attribute_table = 0;
    bg0 = 0;
  end
  always @(posedge clk) if (ce) begin
    case (cycle[2:0])
    1: current_name_table <= vram_data;
    3: current_attribute_table <= (!loopy[1] && !loopy[6]) ? vram_data[1:0] :
                                  ( loopy[1] && !loopy[6]) ? vram_data[3:2] :
                                  (!loopy[1] &&  loopy[6]) ? vram_data[5:4] :
                                                             vram_data[7:6];
    5: bg0 <= vram_data; // Pattern table bitmap #0
//    7: bg1 <= vram_data; // Pattern table bitmap #1
    endcase
    if (enable) begin
      playfield_pipe_1[14:0] <= playfield_pipe_1[15:1];
      playfield_pipe_2[14:0] <= playfield_pipe_2[15:1];
      playfield_pipe_3[7:0] <= playfield_pipe_3[8:1];
      playfield_pipe_4[7:0] <= playfield_pipe_4[8:1];
      // Load the new values into the shift registers at the last pixel.
      if (cycle[2:0] == 7) begin
        playfield_pipe_1[15:8] <= {bg0[0], bg0[1], bg0[2], bg0[3], bg0[4], bg0[5], bg0[6], bg0[7]};
        playfield_pipe_2[15:8] <= {bg1[0], bg1[1], bg1[2], bg1[3], bg1[4], bg1[5], bg1[6], bg1[7]};
        playfield_pipe_3[8] <= current_attribute_table[0];
        playfield_pipe_4[8] <= current_attribute_table[1];
      end
    end
  end
  assign name_table = current_name_table;
  wire [3:0] i = {1'b0, fine_x_scroll};
  assign pixel = {playfield_pipe_4[i], playfield_pipe_3[i],
                  playfield_pipe_2[i], playfield_pipe_1[i]};
endmodule  // BgPainter
module PaletteRam(input clk, input ce, input [4:0] addr, input [5:0] din, output [5:0] dout, input write);
  reg [5:0] palette [0:31];
  initial begin
     //$readmemh("oam_palette.txt", palette);
  end
  // Force read from backdrop channel if reading from any addr 0.
  wire [4:0] addr2 = (addr[1:0] == 0) ? 0 : addr;
  assign dout = palette[addr2];
  always @(posedge clk) if (ce && write) begin
    // Allow writing only to x0
    if (!(addr[3:2] != 0 && addr[1:0] == 0))
      palette[addr2] <= din;
  end
endmodule  // PaletteRam
module NfiVe32_RF (
	input			HCLK,							// System clock
	input			WR,
	input [ 4:0]	RA,
	input [ 4:0]	RB,
	input [ 4:0]	RW,
	input [31:0]	DW, 
	output [31:0]	DA, 
	output [31:0]	DB
);
 	reg [31:0] RF [31:0];

	assign DA = RF[RA] & {32{~(RA==5'd0)}};
	assign DB = RF[RB] & {32{~(RB==5'd0)}};
	
	always @ (posedge HCLK) 
		if(WR)
			if(RW!=5'd0) begin 
				RF[RW] <= DW;
				//#1 $display("Write: RF[%d]=0x%X []", RW, RF[RW]);
			end
endmodule
module blake2s_G(
                 input wire [31 : 0]  a,
                 input wire [31 : 0]  b,
                 input wire [31 : 0]  c,
                 input wire [31 : 0]  d,
                 input wire [31 : 0]  m0,
                 input wire [31 : 0]  m1,

                 output wire [31 : 0] a_prim,
                 output wire [31 : 0] b_prim,
                 output wire [31 : 0] c_prim,
                 output wire [31 : 0] d_prim
                );


  //----------------------------------------------------------------
  // Wires.
  //----------------------------------------------------------------
  reg [31 : 0] a1;
  reg [31 : 0] a2;
  reg [31 : 0] b1;
  reg [31 : 0] b2;
  reg [31 : 0] b3;
  reg [31 : 0] b4;
  reg [31 : 0] c1;
  reg [31 : 0] c2;
  reg [31 : 0] d1;
  reg [31 : 0] d2;
  reg [31 : 0] d3;
  reg [31 : 0] d4;


  //----------------------------------------------------------------
  // Concurrent connectivity for ports.
  //----------------------------------------------------------------
  assign a_prim = a2;
  assign b_prim = b4;
  assign c_prim = c2;
  assign d_prim = d4;


  //----------------------------------------------------------------
  // G_function
  //----------------------------------------------------------------
  always @*
    begin : G_function
      a1 = a + b + m0;

      d1 = d ^ a1;
      d2 = {d1[15 : 0], d1[31 : 16]};

      c1 = c + d2;

      b1 = b ^ c1;
      b2 = {b1[11 : 0], b1[31 : 12]};

      a2 = a1 + b2 + m1;

      d3 = d2 ^ a2;
      d4 = {d3[7 : 0], d3[31 : 8]};

      c2 = c1 + d4;

      b3 = b2 ^ c2;
      b4 = {b3[6 : 0], b3[31 : 7]};
    end // G_function
endmodule // blake2s_G
module FF(input clk,input d, output q );

 sky130_fd_sc_hd__dfxtp_4 x (
    .Q(qw)  ,
    .CLK(clk),
    .D(d)
);


 sky130_fd_sc_hd__inv_1 inv(
    .Y(q),
    .A(qw)
);

endmodule
module blabla_qr(
                 input wire [63 : 0]  a,
                 input wire [63 : 0]  b,
                 input wire [63 : 0]  c,
                 input wire [63 : 0]  d,

                 output wire [63 : 0] a_prim,
                 output wire [63 : 0] b_prim,
                 output wire [63 : 0] c_prim,
                 output wire [63 : 0] d_prim
                );

  //----------------------------------------------------------------
  // Wires.
  //----------------------------------------------------------------
  reg [63 : 0] internal_a_prim;
  reg [63 : 0] internal_b_prim;
  reg [63 : 0] internal_c_prim;
  reg [63 : 0] internal_d_prim;


  //----------------------------------------------------------------
  // Concurrent connectivity for ports.
  //----------------------------------------------------------------
  assign a_prim = internal_a_prim;
  assign b_prim = internal_b_prim;
  assign c_prim = internal_c_prim;
  assign d_prim = internal_d_prim;


  //----------------------------------------------------------------
  // qr
  //
  // The actual quarterround function.
  //----------------------------------------------------------------
  always @*
    begin : qr
      reg [63 : 0] a0;
      reg [63 : 0] a1;
      reg [63 : 0] b0;
      reg [63 : 0] b1;
      reg [63 : 0] b2;
      reg [63 : 0] b3;
      reg [63 : 0] c0;
      reg [63 : 0] c1;
      reg [63 : 0] d0;
      reg [63 : 0] d1;
      reg [63 : 0] d2;
      reg [63 : 0] d3;

      a0 = a + b;
      d0 = d ^ a0;
      d1 = {d0[15 : 0], d0[31 : 16]};
      c0 = c + d1;
      b0 = b ^ c0;
      b1 = {b0[19 : 0], b0[31 : 20]};
      a1 = a0 + b1;
      d2 = d1 ^ a1;
      d3 = {d2[23 : 0], d2[31 : 24]};
      c1 = c0 + d3;
      b2 = b1 ^ c1;
      b3 = {b2[24 : 0], b2[31 : 25]};

      internal_a_prim = a1;
      internal_b_prim = b3;
      internal_c_prim = c1;
      internal_d_prim = d3;
    end // qr
endmodule // blabla_qr
module sri
  // This is a shift register that sends data out to the di lines of
  // spi slaves.
  #(parameter DATA_WIDTH=16)
  (input clk,
   input resetb,
   input [DATA_WIDTH-1:0] datai,
   input sample,
   input shift,
   output din
   );

   reg [DATA_WIDTH-1:0] sr_reg;
   assign din = sr_reg[DATA_WIDTH-1];

`ifdef SYNC_RESET
   always @(posedge clk) begin
`else
   always @(posedge clk or negedge resetb) begin
`endif
      if(!resetb) begin
         sr_reg <= 0;
      end else begin
         if(sample) begin
            sr_reg <= datai;
         end else if(shift) begin
            sr_reg <= sr_reg << 1;
         end
      end
   end
endmodule
module sro
  // This is a shift register that receives data on the dout lines
  // from spi slaves.
  #(parameter DATA_WIDTH=16)
  (input clk,
   input resetb,
   input shift,
   input dout,
   output reg [DATA_WIDTH-1:0] datao
   );
   reg                     dout_s;

`ifdef SYNC_RESET
   always @(posedge clk) begin
`else
   always @(posedge clk or negedge resetb) begin
`endif
      if(!resetb) begin
         dout_s <= 0;
         datao <= 0;
      end else begin
         dout_s <= dout;
         if(shift) begin
            datao <= { datao[DATA_WIDTH-2:0], dout_s };
         end
      end
   end
endmodule
module AHB_SRAM_TB;
    localparam SRAM_AW = 10;

    reg  HCLK;
    reg  HRESETn;

    wire                    HREADY; 
    reg                     HWRITE;
    reg  [2:0]              HSIZE;
    reg  [1:0]              HTRANS;
    reg  [31:0]             HADDR, HWDATA;
    wire [31:0]             HRDATA; 

    wire [31:0]             SRAMRDATA;  // SRAM Read Data
    wire [3:0]              SRAMWEN;    // SRAM write enable (active high)
    wire [31:0]             SRAMWDATA;  // SRAM write data
    wire                    SRAMCS;     // SRAM Chip Select (active high)
    wire [SRAM_AW-1:0]      SRAMADDR;    // SRAM address
        
    always #5 HCLK = !HCLK;

    initial begin
        $dumpfile("ahb_srm_tb.vcd");
        $dumpvars;
    //$monitor("rdata=0x%0h",rdata);

        # 45_000_000 $finish;
    end

    // RESET
    initial begin
        HCLK = 0;
        HRESETn = 1;
		#10;
		@(posedge HCLK);
		HRESETn = 0;
		#100;
		@(posedge HCLK);
		HRESETn = 1;
    end
    

    AHB_SRAM #( .AW(SRAM_AW+2) ) MUV ( 
        .HCLK(HCLK),
        .HRESETn(HRESETn),
    
        // AHB-Lite Slave Interface
        .HSEL(1'b1),
        .HREADYOUT(HREADY),
        .HREADY(HREADY),
        .HWDATA(HWDATA),
        .HRDATA(HRDATA),
        .HSIZE(HSIZE),
        .HWRITE(HWRITE),
        .HTRANS(HTRANS),
        .HADDR(HADDR),

        .SRAMRDATA(SRAMRDATA),
        .SRAMWEN(SRAMWEN),  
        .SRAMWDATA(SRAMWDATA),
        .SRAMCS(SRAMCS),   
        .SRAMADDR(SRAMADDR) 
);   


sram32 #( .AW(SRAM_AW), .VERBOSE(0) ) SRAM (
    .clk(HCLK),
    .cs(SRAMCS),
    .we(SRAMWEN),
    .A(SRAMADDR),
    .Di(SRAMWDATA),
    .Do(SRAMRDATA)
);

`include "includes/AHB_tasks.vh"

// test case
reg [31:0] rdata;
initial begin
    @(posedge HRESETn);
    #200;
    AHB_WRITE_WORD(32'h0000_0000, 32'h44_33_22_11);
    #25;
    AHB_READ_WORD(32'h0000_0000, rdata);
    #25;
    `CHECK_W(32'h44_33_22_11, 1);
    #25;
    AHB_READ_HALF(32'h0000_0000, rdata);
    #25;
    `CHECK_H(16'h22_11, 2);
    #25;
    AHB_READ_BYTE(32'h0000_0000, rdata);
    #25;
    `CHECK_B(8'h11, 3);
    #25;
    AHB_WRITE_WORD(32'h000F_FFF0, 32'hABCD_1234);
    #25;
    AHB_READ_WORD(32'h000F_FFF0, rdata);
    #25;
    `CHECK_W(32'hABCD_1234, 4);
    #100;
    // Read after write
    AHB_WRITE_READ_WORD(32'h0000_0A00, 32'h0000_0000, 32'hDEADBEEF, rdata);
    #100;
    AHB_READ_WORD(32'h0000_0A00, rdata);
    #25;
    `CHECK_W(32'hDEADBEEF, 5);
    $finish;
end

endmodule
module regfile_tb;
	// Declarations
	reg  HCLK;
	reg  WR;
	reg [4:0]  RA;
	reg [4:0]  RB;
	reg [4:0]  RW;
	reg [31:0]  DW;
	wire [31:0]  DA;
	wire [31:0]  DB;

	// Instantiation of Unit Under Test
	regfile uut (
		.HCLK(HCLK),
		.WR(WR),
		.RA(RA),
		.RB(RB),
		.RW(RW),
		.DW(DW),
		.DA(DA),
		.DB(DB)
	);
	
	        initial begin
            $dumpfile("out2.vcd"); 
            // vcd dump file
            $dumpvars; 
            // dump everything

	end
	
	initial begin
	    HCLK =0;
	    //Inputs init:ialization
	   forever begin:   block1
        if (HCLK> 400)begin 
       disable block1;
       end
        else #(5) HCLK<=~HCLK;

       end


	end
	
	
	
	initial begin
		// Input Initialization
		WR = 1'b0;
		RA = 5'b00101;
		RB = 5'b01010;
		RW = 5'b00000;
		DW = 32'b0000000000000000000000000000000000000;
		#10;
		
		

		WR = 1'b1;
		RA = 5'b00101;
		RB = 5'b01010;
		RW =5'b00101;
		DW = 32'b00000000000000000000000001100100;
		#10;
		
	`CHECK_DA(32'b00000000000000000000000001100100, 1);
    //`CHECK_DB(5'b01010, 1);	
		WR = 1'b1;
		RA = 5'b00101;
		RB = 5'b01010;
		RW = 5'b01010;
		DW = 32'b00000000000000000000000011001000;
		#10;
	`CHECK_DA(32'b00000000000000000000000001100100, 2);
	`CHECK_DB(32'b00000000000000000000000011001000, 3);	
		
	    WR = 1'b1;
		RA =  5'b10100;
		RB =  5'b01010;
		RW = 5'b10100;
		DW = 32'b11111111111110110110101111000010;
		#100;

	`CHECK_DA(32'b11111111111110110110101111000010, 4);
	`CHECK_DB(32'b00000000000000000000000011001000, 5);		
		
		
				
	  WR = 1'b1;
		RA = 5'b10100;
		RB = 5'b01010;
		RW = 5'b10100;
		DW = 32'b00000000000000000000001110000011;
		#10;
    `CHECK_DA(32'b00000000000000000000001110000011, 6);
	`CHECK_DB(32'b00000000000000000000000011001000, 7);	
		// Reset
		#100;

      WR = 1'b0;
		RA = 5'b10100;
		RB = 5'b01010;
		RW = 5'b10100;
		DW = 32'b10000000011100000000001110000011;
		#10;
    `CHECK_DA(32'b00000000000000000000001110000011, 8);
	`CHECK_DB(32'b00000000000000000000000011001000, 9);	
		// Reset
		#100;
 
    $finish;
end


endmodule
module regfile (
	input			HCLK,							// System clock
	input			WR,
	input [ 4:0]	RA,
	input [ 4:0]	RB,
	input [ 4:0]	RW,
	input [31:0]	DW, 
	output [31:0]	DA, 
	output [31:0]	DB
);
 	reg [31:0] RF [31:0];

	assign DA = RF[RA] & {32{~(RA==5'd0)}};
	assign DB = RF[RB] & {32{~(RB==5'd0)}};
	
	always @ (posedge HCLK) 
		if(WR)
			if(RW!=5'd0) begin 
				RF[RW] <= DW;
				//#1 $display("Write: RF[%d]=0x%X []", RW, RF[RW]);
			end
endmodule
module ram #(
    parameter RAM_FILENAME        = "../../../roms/ram.hex"
) (
    input clk,              // clock signal
    input [12:0] address,   // address bus
    input w_en,             // active high write enable strobe
    input [7:0] din,        // 8-bit data bus (input)
    output reg [7:0] dout   // 8-bit data bus (output)
);

    reg [7:0] ram_data[0:8191];

    initial
        $readmemh(RAM_FILENAME, ram_data, 0, 8191);

    always @(posedge clk)
    begin
        dout <= ram_data[address];
        if (w_en) ram_data[address] <= din;
    end

endmodule
module clock(
    input clk25,            // 25MHz clock master clock
    input rst_n,            // active low synchronous reset

    // Clock enables
    output reg cpu_clken    // 1MHz clock enable for the CPU and devices
    );

    // generate clock enable once every
    // 25 clocks. This will (hopefully) make
    // the 6502 run at 1 MHz or 1Hz
    //
    // the clock division counter is synchronously
    // reset using rst_n to avoid undefined signals
    // in simulation
    //

    //`define SLOWCPU
    `ifdef SLOWCPU
        reg [25:0] clk_div;
        always @(posedge clk25)
        begin
            // note: clk_div should be compared to
            //       N-1, where N is the clock divisor
            if ((clk_div == 24999999) || (rst_n == 1'b0))
                clk_div <= 0;
            else
                clk_div <= clk_div + 1'b1;

            cpu_clken <= (clk_div[25:0] == 0);
        end
    `else
        reg [4:0] clk_div;
        always @(posedge clk25)
        begin
            // note: clk_div should be compared to
            //       N-1, where N is the clock divisor
            if ((clk_div == 24) || (rst_n == 1'b0))
                clk_div <= 0;
            else
                clk_div <= clk_div + 1'b1;

            cpu_clken <= (clk_div[4:0] == 0);
        end
    `endif

endmodule
module rom_basic #(
    parameter BASIC_FILENAME = "../../../roms/basic.hex"
) (
    input clk,              // clock signal
    input [11:0] address,   // address bus
    output reg [7:0] dout   // 8-bit data bus (output)
);

    reg [7:0] rom_data[0:4095];

    initial
        $readmemh(BASIC_FILENAME, rom_data, 0, 4095);

    always @(posedge clk)
        dout <= rom_data[address];

endmodule
module pwr_reset(
    input clk25,        // 25Mhz master clock
    input rst_n,        // active low synchronous reset
    input enable,       // clock enable
    output rst          // active high synchronous system reset
    );

    reg hard_reset;
    reg [5:0] reset_cnt;
    wire pwr_up_flag = &reset_cnt;

    always @(posedge clk25)
    begin
        if (rst_n == 1'b0)
        begin
            reset_cnt  <= 6'b0;
            hard_reset <= 1'b0;
        end
        else if (enable)
        begin
            if (!pwr_up_flag)
                reset_cnt <= reset_cnt + 6'b1;

            hard_reset <= pwr_up_flag;
        end
    end

    assign rst = ~hard_reset;

endmodule
module rom_wozmon #(
    parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
) (
    input clk,              // clock signal
    input [7:0] address,    // address bus
    output reg [7:0] dout   // 8-bit data bus (output)
);

    reg [7:0] rom_data[0:255];

    initial
        $readmemh(WOZMON_ROM_FILENAME, rom_data, 0, 255);

    always @(posedge clk)
        dout <= rom_data[address];

endmodule
module vga_tb;

    reg clk25, rst, address, w_en, blink_clken;
    reg [7:0] din;
    wire vga_h_sync, vga_v_sync, vga_red, vga_grn, vga_blu;

    //////////////////////////////////////////////////////////////////////////
    // Setup dumping of data for inspection

    initial begin

        clk25 = 1'b0;
        rst = 1'b0;
        address = 1'b0;
        w_en = 1'b0;
        blink_clken = 1'b0;
        din = 8'd0;

        #5
        rst = 1'b1;
        #5
        rst = 1'b0;

        $display("Starting...");
        $dumpfile("vga_tb.vcd");
        $dumpvars;

        //#180000
        //uart_rx = 1'b0;
        //#400
        //uart_rx = 1'b1;
        //#400
        //uart_rx = 1'b0;
        //#400
        //uart_rx = 1'b1;
        //#800
        //uart_rx = 1'b0;
        //#1600
        //uart_rx = 1'b1;
 

        #50000000 $display("Stopping...");
        $finish;
    end

    //////////////////////////////////////////////////////////////////////////
    // Clock

    always
        #20 clk25 = !clk25;

    //////////////////////////////////////////////////////////////////////////
    // Core of system
    vga my_vga (
        .clk25(clk25),
        .enable(1'b1),
        .rst(rst),
        .vga_h_sync(vga_h_sync),
        .vga_v_sync(vga_v_sync),
        .vga_red(vga_red),
        .vga_grn(vga_grn),
        .vga_blu(vga_blu),
        .address(address),
        .w_en(w_en),
        .din(din)
    );

endmodule
module uart_tb;

    reg clk25, enable, rst, w_en, uart_rx;
    reg [2:0] state;
    reg [1:0] address;
    reg [7:0] din;
    wire [7:0] dout;
    wire uart_tx, uart_cts;

    //////////////////////////////////////////////////////////////////////////
    // Setup dumping of data for inspection

    initial begin

        state = 3'd0;

        clk25 = 1'b0;
        rst = 1'b1;

        enable = 1'b0;
        w_en = 1'b0;
        uart_rx = 1'b1;
        address = 2'b11;
        din = 8'b0;

        $display("Starting...");
        $dumpfile("uart_tb.vcd");
        $dumpvars;

        #40
        rst = 1'b0;     // reset release
        state = 3'd1;

        #1                  // TX first byte - ignored
        address = 2'b10;
        din = 8'b00101010;
        enable = 1'b1;
        w_en = 1'b1;
        state = 3'd3;

        #2
        w_en = 1'b0;
        enable = 1'b0;
        state = 3'd4;

        #40                 // TX second byte
        address = 2'b10;
        din = 8'b00101010;
        enable = 1'b1;
        w_en = 1'b1;
        state = 3'd3;

        #2
        w_en = 1'b0;
        enable = 1'b0;
        state = 3'd4;

        #6000
        state = 3'd5;

        uart_rx = 1'b1;
        #434 uart_rx = 1'b0; // start
        #434 uart_rx = 1'b0; // 1
        #434 uart_rx = 1'b1; // 2
        #434 uart_rx = 1'b0; // 3
        #434 uart_rx = 1'b1; // 4
        #434 uart_rx = 1'b0; // 5
        #434 uart_rx = 1'b1; // 6
        #434 uart_rx = 1'b0; // 7
        #434 uart_rx = 1'b1; // 8
        #434 uart_rx = 1'b1; // stop bit 1
        #434 uart_rx = 1'b1; // stop bit 2
        state = 3'd6;
        
        #6000
        address = 2'b00;
        enable = 1'b1;
        state = 3'd7;
        #20
        enable = 1'b0;

        #10000 $display("Stopping...");
        $finish;
    end

    //////////////////////////////////////////////////////////////////////////
    // Clock

    always
        #1 clk25 = !clk25;

    //////////////////////////////////////////////////////////////////////////
    // Core of system
    uart #(
        .ClkFrequency(25000000),
        .Baud(115200),
        .Oversampling(8)
    ) my_uart (
        .clk(clk25),
        .enable(1'b1),
        .rst(rst),
        .address(address),
        .w_en(w_en),
        .din(din),
        .dout(dout),
        .uart_rx(uart_rx),
        .uart_tx(uart_tx),
        .uart_cts(uart_cts)
    );

endmodule
module apple1_tb #(
    parameter BASIC_FILENAME      = "../roms/basic.hex",
    parameter FONT_ROM_FILENAME   = "../roms/vga_font_bitreversed.hex",
    parameter RAM_FILENAME        = "../roms/ram.hex",
    parameter VRAM_FILENAME       = "../roms/vga_vram.bin",
    parameter WOZMON_ROM_FILENAME = "../roms/wozmon.hex"
);

    reg clk25, uart_rx, rst_n;
    wire uart_tx, uart_cts;

    //////////////////////////////////////////////////////////////////////////
    // Setup dumping of data for inspection

    initial begin

        clk25 = 1'b0;
        uart_rx = 1'b1;
        rst_n = 1'b0;
        #40 rst_n = 1'b1;

        $display("Starting...");
        $dumpfile("apple1_top_tb.vcd");
        $dumpvars;

        #180000
        uart_rx = 1'b0;
        #400
        uart_rx = 1'b1;
        #400
        uart_rx = 1'b0;
        #400
        uart_rx = 1'b1;
        #800
        uart_rx = 1'b0;
        #1600
        uart_rx = 1'b1;
 

        #1000000 $display("Stopping...");
        $finish;
    end

    //////////////////////////////////////////////////////////////////////////
    // Clock

    always
        #20 clk25 = !clk25;

    //////////////////////////////////////////////////////////////////////////
    // Core of system
    apple1 #(
        .BASIC_FILENAME (BASIC_FILENAME),
        .FONT_ROM_FILENAME (FONT_ROM_FILENAME),
        .RAM_FILENAME (RAM_FILENAME),
        .VRAM_FILENAME (VRAM_FILENAME),
        .WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
    ) core_top (
        .clk25(clk25),
        .rst_n(rst_n),
        .uart_rx(uart_rx),
        .uart_tx(uart_tx),
        .uart_cts(uart_cts)
    );

endmodule
module async_transmitter(
    input clk,
    input rst,
    input TxD_start,
    input [7:0] TxD_data,
    output TxD,
    output TxD_busy
    );

    // Assert TxD_start for (at least) one clock cycle to start transmission of TxD_data
    // TxD_data is latched so that it doesn't have to stay valid while it is being sent

    parameter ClkFrequency = 25000000;	// 25MHz
    parameter Baud = 115200;

    ////////////////////////////////
    wire BitTick;
    BaudTickGen #(ClkFrequency, Baud) tickgen(.clk(clk), .rst(rst), .enable(TxD_busy), .tick(BitTick));

    reg [3:0] TxD_state;
    reg [7:0] TxD_shift;

    wire TxD_ready = (TxD_state==0);
    assign TxD_busy = ~TxD_ready;

    always @(posedge clk or posedge rst)
    begin
        if (rst)
        begin
            TxD_state <= 0;
            TxD_shift <= 0;
        end
        else
        begin
            if(TxD_ready & TxD_start)
                TxD_shift <= TxD_data;
            else
                if(TxD_state[3] & BitTick)
                    TxD_shift <= (TxD_shift >> 1);

            case(TxD_state)
                4'b0000: if(TxD_start) TxD_state <= 4'b0100;
                4'b0100: if(BitTick) TxD_state <= 4'b1000;  // start bit
                4'b1000: if(BitTick) TxD_state <= 4'b1001;  // bit 0
                4'b1001: if(BitTick) TxD_state <= 4'b1010;  // bit 1
                4'b1010: if(BitTick) TxD_state <= 4'b1011;  // bit 2
                4'b1011: if(BitTick) TxD_state <= 4'b1100;  // bit 3
                4'b1100: if(BitTick) TxD_state <= 4'b1101;  // bit 4
                4'b1101: if(BitTick) TxD_state <= 4'b1110;  // bit 5
                4'b1110: if(BitTick) TxD_state <= 4'b1111;  // bit 6
                4'b1111: if(BitTick) TxD_state <= 4'b0010;  // bit 7
                4'b0010: if(BitTick) TxD_state <= 4'b0011;  // stop1
                4'b0011: if(BitTick) TxD_state <= 4'b0000;  // stop2
                default: if(BitTick) TxD_state <= 4'b0000;
            endcase
        end
    end

    assign TxD = (TxD_state<4) | (TxD_state[3] & TxD_shift[0]);
endmodule
module BaudTickGen(
    input clk, rst, enable,
    output tick  // generate a tick at the specified baud rate * oversampling
    );

    parameter ClkFrequency = 25000000;
    parameter Baud = 115200;
    parameter Oversampling = 1;

    function integer log2(input integer v); begin log2=0; while(v>>log2) log2=log2+1; end endfunction

    localparam AccWidth = log2(ClkFrequency/Baud)+8;  // +/- 2% max timing error over a byte
    reg [AccWidth:0] Acc;
    localparam ShiftLimiter = log2(Baud*Oversampling >> (31-AccWidth));  // this makes sure Inc calculation doesn't overflow
    localparam Inc = ((Baud*Oversampling << (AccWidth-ShiftLimiter))+(ClkFrequency>>(ShiftLimiter+1)))/(ClkFrequency>>ShiftLimiter);

    always @(posedge clk)
    begin
        if (rst)
            Acc <= 0;
        else
            if(enable) Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0];
    end
    assign tick = Acc[AccWidth];

endmodule
module debounce(
    input       clk25,      // 25MHz clock
    input       rst,        // active high reset
    
    input       sig_in,     // input signal
    output reg  sig_out     // debounced output signal
);

wire clk_enb;       // enable triggering at clk25 divided by 64
reg [5:0] clk_div;  // clock divider counter

reg sig_ff1;        // first  input signal synchronizer
reg sig_ff2;        // second input signal synchronizer

assign clk_enb = (clk_div == 6'd0);

// clock divider
always @(posedge clk25 or posedge rst)
begin
    if (rst)
        clk_div <= 6'd0;
    else
        clk_div <= clk_div + 6'd1;
end

// debounce timer
always @(posedge clk25 or posedge rst)
begin
    if (rst)
    begin
        sig_out <= 1'b0;
        sig_ff1 <= 1'b0;
        sig_ff2 <= 1'b0;
    end
    else if (clk_enb)
    begin
        // this runs ar approximately 391k Hz
        // giving a debounce time of around 2.5us
        sig_ff1 <= sig_in;
        sig_ff2 <= sig_ff1;
        if ((sig_ff1 ^ sig_ff2) == 1'd0)
        begin
            sig_out <= sig_ff2;
        end
    end
end

endmodule
module arlet_6502(
    input clk,                  // clock signal
    input enable,               // clock enable strobe
    input rst,                  // active high reset signal
    output reg [15:0] ab,       // address bus
    input [7:0] dbi,            // 8-bit data bus (input)
    output reg [7:0] dbo,       // 8-bit data bus (output)
    output reg we,              // active high write enable strobe
    input irq_n,                // active low interrupt request
    input nmi_n,                // active low non-maskable interrupt
    input ready,                // CPU updates when ready = 1
    output [15:0] pc_monitor    // program counter monitor signal for debugging
);

    wire [7:0] dbo_c;
    wire [15:0] ab_c;
    wire we_c;

    cpu arlet_cpu(
        .clk(clk),
        .reset(rst),
        .AB(ab_c),
        .DI(dbi),
        .DO(dbo_c),
        .WE(we_c),
        .IRQ(~irq_n),
        .NMI(~nmi_n),
        .RDY(ready),
        .PC_MONITOR(pc_monitor)
    );

    always @(posedge clk or posedge rst)
    begin
        if (rst)
        begin
            ab <= 16'd0;
            dbo <= 8'd0;
            we <= 1'b0;
        end
        else
            if (enable)
            begin
                ab <= ab_c;
                dbo <= dbo_c;
                we <= we_c;
            end
    end
endmodule
module aholme_6502(
    input clk,
    input enable,
    input reset,
    output [15:0] ab,
    input [7:0] dbi,
    output [7:0] dbo,
    output we,
    input irq,
    input nmi,
    input ready
);

    wire we_c;

    chip_6502 aholme_cpu (
        .clk(clk),
        .phi(clk & enable),
        .res(~reset),
        .so(1'b0),
        .rdy(ready),
        .nmi(nmi_n),
        .irq(irq_n),
        .rw(we_c),
        .dbi(dbi),
        .dbo(dbo),
        .ab(ab)
    );

    assign we = ~we_c;

endmodule
module vram #(
    parameter VRAM_FILENAME       = "../../../roms/vga_vram.bin"
) (
    input clk,                  // clock signal
    input [10:0] read_addr,      // read address bus
    input [10:0] write_addr,     // write address bus
    input r_en,                 // active high read enable strobe
    input w_en,                 // active high write enable strobe
    input [5:0] din,            // 6-bit data bus (input)
    output reg [5:0] dout       // 6-bit data bus (output)
);

    reg [5:0] ram_data[0:2047];

    initial
        $readmemb(VRAM_FILENAME, ram_data, 0, 2047);

    always @(posedge clk)
    begin
        if (r_en) dout <= ram_data[read_addr];
        if (w_en) ram_data[write_addr] <= din;
    end

endmodule
module font_rom #(
    parameter FONT_ROM_FILENAME   = "../../../roms/vga_font_bitreversed.hex"
) (
    input clk,              // clock signal
    input [1:0] mode,       // character mode
    input [5:0] character,  // address bus
    input [3:0] pixel,      // address of the pixel to output
    input [4:0] line,       // address of the line to output
    output reg out          // single pixel from address and pixel pos
    );

    reg [7:0] rom[0:1023];

    initial
        $readmemh(FONT_ROM_FILENAME, rom, 0, 1023);

    // double height of pixel by ignoring bit 0
    wire [3:0] line_ptr = line[4:1];

    // Note: Quartus II reverses the pixels when we do:
    //
    // rom[address][bitindex] 
    //
    // directly, so we use an intermediate 
    // signal, romout, to work around this 
    // problem.
    //
    // IceCube2 and Yosys don't seem to have this problem.
    //
    
    reg [7:0] romout;
    
    always @(posedge clk)
    begin
        // mode
        // 00 - normal
        // 01 - vertical scanlines
        // 10 - horizontal scanlines
        // 11 - dotty mode
        
        romout = rom[(character * 10) + {2'd0, line_ptr}];
        
        out <= (mode[1] & line[0]) ? 1'b0 :
               (mode[0] & pixel[0]) ? 1'b0 :
               romout[pixel[3:1]];
    end

endmodule
module MUX #(
    parameter N=1
) (
    output wire o,
    input  wire i,
    input  wire [N-1:0] s,
    input  wire [N-1:0] d);

    assign o = (|s) ? &(d|(~s)) : i;
endmodule
module LOGIC (
    input  [`NUM_NODES-1:0] i,
    output [`NUM_NODES-1:0] o);

    `include "../rtl/cpu/aholme/chip_6502_logic.inc"
endmodule
module chip_6502 (
    input           clk,    // FPGA clock
    input           phi,    // 6502 clock
    input           res,
    input           so,
    input           rdy,
    input           nmi,
    input           irq,
    input     [7:0] dbi,
    output    [7:0] dbo,
    output          rw,
    output          sync,
    output   [15:0] ab);

    // Node states
    wire [`NUM_NODES-1:0] no;
    reg  [`NUM_NODES-1:0] ni;
    reg  [`NUM_NODES-1:0] q = 0;

    LOGIC logic_00 (.i(ni), .o(no));

    always @ (posedge clk)
        q <= no;

    always @* begin
        ni = q;

        ni[`NODE_vcc ]  = 1'b1;
        ni[`NODE_vss ]  = 1'b0;
        ni[`NODE_res ]  = res;
        ni[`NODE_clk0]  = phi;
        ni[`NODE_so  ]  = so;
        ni[`NODE_rdy ]  = rdy;
        ni[`NODE_nmi ]  = nmi;
        ni[`NODE_irq ]  = irq;

       {ni[`NODE_db7],ni[`NODE_db6],ni[`NODE_db5],ni[`NODE_db4],
        ni[`NODE_db3],ni[`NODE_db2],ni[`NODE_db1],ni[`NODE_db0]} = dbi[7:0];
    end

    assign dbo[7:0] = {
        no[`NODE_db7],no[`NODE_db6],no[`NODE_db5],no[`NODE_db4],
        no[`NODE_db3],no[`NODE_db2],no[`NODE_db1],no[`NODE_db0]
    };

    assign ab[15:0] = {
        no[`NODE_ab15], no[`NODE_ab14], no[`NODE_ab13], no[`NODE_ab12],
        no[`NODE_ab11], no[`NODE_ab10], no[`NODE_ab9],  no[`NODE_ab8],
        no[`NODE_ab7],  no[`NODE_ab6],  no[`NODE_ab5],  no[`NODE_ab4],
        no[`NODE_ab3],  no[`NODE_ab2],  no[`NODE_ab1],  no[`NODE_ab0]
    };

    assign rw   = no[`NODE_rw];
    assign sync = no[`NODE_sync];

endmodule
module ALU( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC, RDY );
	input clk;
	input right;
	input [3:0] op;		// operation
	input [7:0] AI;
	input [7:0] BI;
	input CI;
	input BCD;		// BCD style carry
	output [7:0] OUT;
	output CO;
	output V;
	output Z;
	output N;
	output HC;
	input RDY;

reg [7:0] OUT;
reg CO;
wire V;
wire Z;
reg N;
reg HC;

reg AI7;
reg BI7;
reg [8:0] temp_logic;
reg [7:0] temp_BI;
reg [4:0] temp_l;
reg [4:0] temp_h;
wire [8:0] temp = { temp_h, temp_l[3:0] };
wire adder_CI = (right | (op[3:2] == 2'b11)) ? 0 : CI;

// calculate the logic operations. The 'case' can be done in 1 LUT per
// bit. The 'right' shift is a simple mux that can be implemented by
// F5MUX.
always @*  begin
	case( op[1:0] )
	    2'b00: temp_logic = AI | BI;
	    2'b01: temp_logic = AI & BI;
	    2'b10: temp_logic = AI ^ BI;
	    2'b11: temp_logic = AI;
	endcase

	if( right )
	    temp_logic = { AI[0], CI, AI[7:1] };
end

// Add logic result to BI input. This only makes sense when logic = AI.
// This stage can be done in 1 LUT per bit, using carry chain logic.
always @* begin
	case( op[3:2] )
	    2'b00: temp_BI = BI;	// A+B
	    2'b01: temp_BI = ~BI;	// A-B
	    2'b10: temp_BI = temp_logic;	// A+A
	    2'b11: temp_BI = 0;		// A+0
	endcase	
end

// HC9 is the half carry bit when doing BCD add
wire HC9 = BCD & (temp_l[3:1] >= 3'd5);

// CO9 is the carry-out bit when doing BCD add
wire CO9 = BCD & (temp_h[3:1] >= 3'd5);

// combined half carry bit
wire temp_HC = temp_l[4] | HC9;

// perform the addition as 2 separate nibble, so we get
// access to the half carry flag
always @* begin
	temp_l = temp_logic[3:0] + temp_BI[3:0] + adder_CI;
	temp_h = temp_logic[8:4] + temp_BI[7:4] + temp_HC;
end

// calculate the flags 
always @(posedge clk)
    if( RDY ) begin
	AI7 <= AI[7];
	BI7 <= temp_BI[7];
	OUT <= temp[7:0];
	CO  <= temp[8] | CO9;
	N   <= temp[7];
	HC  <= temp_HC;
    end

assign V = AI7 ^ BI7 ^ CO ^ N;
assign Z = ~|OUT;

endmodule
module pll(
	input  clock_in,
	output clock_out,
	output locked
	);

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

endmodule
module clock_pll(REFERENCECLK,
                 PLLOUTCORE,
                 PLLOUTGLOBAL,
                 RESET);

input REFERENCECLK;
input RESET;    /* To initialize the simulation properly, the RESET signal (Active Low) must be asserted at the beginning of the simulation */ 
output PLLOUTCORE;
output PLLOUTGLOBAL;

SB_PLL40_CORE clock_pll_inst(.REFERENCECLK(REFERENCECLK),
                             .PLLOUTCORE(PLLOUTCORE),
                             .PLLOUTGLOBAL(PLLOUTGLOBAL),
                             .EXTFEEDBACK(),
                             .DYNAMICDELAY(),
                             .RESETB(RESET),
                             .BYPASS(1'b0),
                             .LATCHINPUTVALUE(),
                             .LOCK(),
                             .SDI(),
                             .SDO(),
                             .SCLK());

//\\ Fin=16, Fout=25;
defparam clock_pll_inst.DIVR = 4'b0000;
defparam clock_pll_inst.DIVF = 7'b0110001;
defparam clock_pll_inst.DIVQ = 3'b101;
defparam clock_pll_inst.FILTER_RANGE = 3'b001;
defparam clock_pll_inst.FEEDBACK_PATH = "SIMPLE";
defparam clock_pll_inst.DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
defparam clock_pll_inst.FDA_FEEDBACK = 4'b0000;
defparam clock_pll_inst.DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
defparam clock_pll_inst.FDA_RELATIVE = 4'b0000;
defparam clock_pll_inst.SHIFTREG_DIV_MODE = 2'b00;
defparam clock_pll_inst.PLLOUT_SELECT = "GENCLK";
defparam clock_pll_inst.ENABLE_ICEGATE = 1'b0;

endmodule
module apple1_s3e_starterkit_top #(
    parameter BASIC_FILENAME      = "../../../roms/basic.hex",
    parameter FONT_ROM_FILENAME   = "../../../roms/vga_font_bitreversed.hex",
    parameter RAM_FILENAME        = "../../../roms/ram.hex",
    parameter VRAM_FILENAME       = "../../../roms/vga_vram.bin",
    parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
) (    
    input   CLK_50MHZ,      // the 50 MHz master clock

    // UART I/O signals
    output  UART_TXD,       // UART transmit pin on board
    input   UART_RXD,       // UART receive pin on board
        
    input   PS2_KBCLK,
    input   PS2_KBDAT,

    input   BUTTON,         // Button for RESET
    input   SWITCH,         // Switch between PS/2 input and UART

    output  VGA_R,
    output  VGA_G,
    output  VGA_B,
    output  VGA_HS,
    output  VGA_VS    
);

    //////////////////////////////////////////////////////////////////////////    
    // Registers and Wires
    reg clk25;
    wire [15:0] pc_monitor;

    wire rst_n;    
    assign rst_n = ~BUTTON;

    // generate 25MHz clock from 50MHz master clock
    always @(posedge CLK_50MHZ)
    begin
        clk25 <= ~clk25;
    end    
    
    //////////////////////////////////////////////////////////////////////////    
    // Core of system
    apple1 #(
        .BASIC_FILENAME (BASIC_FILENAME),
        .FONT_ROM_FILENAME (FONT_ROM_FILENAME),
        .RAM_FILENAME (RAM_FILENAME),
        .VRAM_FILENAME (VRAM_FILENAME),
        .WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
    ) apple1_top(
        .clk25(clk25),
        .rst_n(rst_n),         // we don't have any reset pulse..
        .uart_rx(UART_RXD),
        .uart_tx(UART_TXD),
        //.uart_cts(UART_CTS),  // there is no CTS on the board :(
        .ps2_clk(PS2_KBCLK),
        .ps2_din(PS2_KBDAT),
        .ps2_select(SWITCH),
        .vga_h_sync(VGA_HS),
        .vga_v_sync(VGA_VS),
        .vga_red(VGA_R),
        .vga_grn(VGA_G),
        .vga_blu(VGA_B),
        .vga_cls(~rst_n),
        .pc_monitor(pc_monitor)
    );
    
endmodule
module segmentdisplay (
    clk,
    latch,
    hexdigit_in,
    display_out
);

    input  clk,latch;
    input  [3:0] hexdigit_in;
    output reg [0:6] display_out;

    always @(posedge clk)
    begin
        if (latch == 1)
        begin 
            case (hexdigit_in)
                4'b0000:
                    display_out <= 7'b1000000;
                4'b0001:
                    display_out <= 7'b1111001;
                4'b0010:
                    display_out <= 7'b0100100;
                4'b0011:
                    display_out <= 7'b0110000;
                4'b0100:
                    display_out <= 7'b0011001;
                4'b0101:
                    display_out <= 7'b0010010;
                4'b0110:
                    display_out <= 7'b0000010;
                4'b0111:
                    display_out <= 7'b1111000;
                4'b1000:
                    display_out <= 7'b0000000;
                4'b1001:
                    display_out <= 7'b0011000;
                4'b1010:
                    display_out <= 7'b0001000;
                4'b1011:
                    display_out <= 7'b0000011;
                4'b1100:
                    display_out <= 7'b1000110;
                4'b1101:
                    display_out <= 7'b0100001;
                4'b1110:
                    display_out <= 7'b0000110;    
                4'b1111:
                    display_out <= 7'b0001110;
            endcase
        end                                                                                                   
    end
endmodule