dakies/OSS_Verilog huggingface dataset:
module vram
(
	input	wire		clk,
	
	// 显存控制
	input	wire		vram_wen,
	input	wire		vram_wdata,
	input	wire		vram_ren,
	output	reg			vram_rdata,
	input	wire [7:0]	vram_addr,
	
	// vga输入(640 * 480)
	input	wire		hs_i,
	input	wire		vs_i,
	input	wire		axis_en,
	input	wire [10:0]	axis_x,
	input	wire [10:0] axis_y,
	
	// vga输出(640 * 480)
	output	reg			hs_o,
	output	reg			vs_o,
	output	reg [23:0]	rgb_o
);

reg state;
reg [4:0] mesh_x;
reg [4:0] mesh_y;
reg [7:0] mesh_addr;
reg vga_ram[0 : 18 * 13 - 1];

reg hs_i_d0;
reg vs_i_d0;
reg hs_i_d1;
reg vs_i_d1;
reg hs_i_d2;
reg vs_i_d2;
reg axis_en_d0;
reg [10:0] axis_x_d0;
reg [10:0] axis_y_d0;
reg axis_en_d1;
reg [10:0] axis_x_d1;
reg [10:0] axis_y_d1;
reg axis_en_d2;
reg [10:0] axis_x_d2;
reg [10:0] axis_y_d2;

// CPU显存控制
always@(posedge clk)
begin
	if(vram_wen)
		vga_ram[vram_addr] <= vram_wdata;
	if(vram_ren)
		vram_rdata <= vga_ram[vram_addr];
end

// 当前网格坐标(axis/32).
always@(posedge clk)
begin
	mesh_x <= axis_x[9:5] - 1;
	mesh_y <= axis_y[9:5] - 1;
end

// 显存地址
always@(posedge clk)
begin
	mesh_addr <=  mesh_y * 18 + mesh_x;
end

// 当前格子显示状态
always@(posedge clk)
begin
	state <= vga_ram[mesh_addr];
end

// 数据延时对齐
always@(posedge clk)
begin
	axis_en_d0 <= axis_en;
	axis_x_d0 <= axis_x;
	axis_y_d0 <= axis_y;
	
	axis_en_d1 <= axis_en_d0;
	axis_x_d1 <= axis_x_d0;
	axis_y_d1 <= axis_y_d0;
	
	axis_en_d2 <= axis_en_d1;
	axis_x_d2 <= axis_x_d1;
	axis_y_d2 <= axis_y_d1;
end

// 数据延时对齐
always@(posedge clk)
begin
	hs_i_d0 <= hs_i;
	vs_i_d0 <= vs_i;
	
	hs_i_d1 <= hs_i_d0;
	vs_i_d1 <= vs_i_d0;
	
	hs_i_d2 <= hs_i_d1;
	vs_i_d2 <= vs_i_d1;
end

// 图像数据输出
// always@(posedge clk)
always@(negedge clk)
begin
	if(axis_en_d2)
	begin
		if(axis_x_d2 < 32 || axis_x_d2 > (640 - 32) || axis_y_d2 < 32 || axis_y_d2 > (480 - 32)) // 黑色区域
			rgb_o <= 0;
		else if(axis_x_d2 == 32 || axis_x_d2 == (640 - 32) || axis_y_d2 == 32 || axis_y_d2 == (480 - 32)) // 边框线
			rgb_o <= {8'd240, 8'd240, 8'd120};
		else if(axis_y_d2[4:0] == 0 || axis_x_d2[4:0] == 0) // 网格线
			rgb_o <= {8'd80, 8'd40, 8'd80};
		else if(state) // 网格显示
			rgb_o <= {8'd40, 8'd180, 8'd80};
		else
			rgb_o <= 0;
	end
	else
		rgb_o <= 0;
end

// 行场时序输出
// always@(posedge clk)
always@(negedge clk)
begin
	hs_o <= hs_i_d2;
	vs_o <= vs_i_d2;
end

endmodule
module vga_box
#(
	parameter X = 640,
	parameter Y = 480
)
(
	input	wire		clk,
	
	// vga输入时序
	input	wire		hs_i,
	input	wire		vs_i,
	input	wire		axis_en,
	input	wire [10:0]	axis_x,
	input	wire [10:0] axis_y,
	
	// vga输出测试框
	output	reg			hs_o,
	output	reg			vs_o,
	output	reg [15:0]	rgb_o
);

// vga边界像素测试
always@(posedge clk)
begin
	if(axis_en)
	begin
		if(axis_x == 0)
			rgb_o <= {5'b11111,6'b000000,5'b00000}; // 红色
		else if(axis_x == X - 1)
			rgb_o <= {5'b00000,6'b000000,5'b11111}; // 蓝色
		else if(axis_y == 0)
			rgb_o <= {5'b00000,6'b111111,5'b00000}; // 绿色
		else if(axis_y == Y - 1)
			rgb_o <= {5'b11111,6'b111111,5'b11111}; // 白色
		else
			rgb_o <= {5'b00000,6'b00000,5'b00000}; // 黑色
	end
	else
		rgb_o <= {5'b00000,6'b00000,5'b00000}; // 无数据
end

always@(posedge clk)
begin
	hs_o <= hs_i;
	vs_o <= vs_i;
end

endmodule
module vga
#(
	parameter A = 96	, // 行同步信号时间
	parameter B = 48	, // 行消隐后肩时间
	parameter C = 640	, // 行数据有效时间
	parameter D = 16	, // 行消隐前肩时间
	parameter E = 800	, // 行扫描总时间
	parameter F = 2		, // 列同步信号时间
	parameter G = 33	, // 列消隐后肩时间
	parameter H = 480	, // 列数据有效时间
	parameter I = 10	, // 列消隐前肩时间
	parameter K = 525	  // 列扫描总时间
)
(
	input	wire		clk,
	
	// VGA时序输出
	output	reg			hsyn,
	output	reg			vsyn,
	
	// VGA时序伴随坐标
	output	reg			axis_en,
	output	reg [10:0]	axis_x,
	output	reg [10:0]	axis_y
);

reg [12:0] hsyn_cnt;
reg [12:0] vsyn_cnt;

// 行扫描计数器
always@(posedge clk)
begin
	if(hsyn_cnt == E-1)
        hsyn_cnt <= 0;
    else
        hsyn_cnt <= hsyn_cnt + 1;
end

// 列扫描计数器
always@(posedge clk)
begin
	if(hsyn_cnt == E-1)
	begin
        if(vsyn_cnt == K-1)
            vsyn_cnt <= 0;
        else
            vsyn_cnt <= vsyn_cnt + 1;
	end
end

// 行控制
always@(posedge clk)
begin
    if(hsyn_cnt < A)
        hsyn <= 0;
    else
        hsyn <= 1;
end

// 场控制
always@(posedge clk)
begin
    if(vsyn_cnt < F)
        vsyn <= 0;
    else
        vsyn <= 1;
end

// 时序伴随坐标使能.
always@(posedge clk)
begin
    if(vsyn_cnt >= F + G && vsyn_cnt < F + G + H)
    begin
        if(hsyn_cnt >= A + B && hsyn_cnt < A + B + C)
            axis_en <= 1;
        else
            axis_en <= 0;
    end
    else
        axis_en <= 0;
end

//数据x坐标
always@(posedge clk)
begin
    if(vsyn_cnt >= F + G && vsyn_cnt < F + G + H)
    begin
        if(hsyn_cnt >= A + B && hsyn_cnt < A + B + C)
            axis_x <= hsyn_cnt - (A + B);
        else
            axis_x <= 0;
    end
    else
        axis_x <= 0;
end

//数据y坐标
always@(posedge clk)
begin
    if(vsyn_cnt >= F + G && vsyn_cnt < F + G + H)
        axis_y <= vsyn_cnt - (F + G);
    else
        axis_y <= 0;
end

endmodule
module vga_colorbar
#(
	parameter X = 640,
	parameter Y = 480
)
(
	input	wire		clk,
	
	// vga输入时序
	input	wire		hs_i,
	input	wire		vs_i,
	input	wire		axis_en,
	input	wire [10:0]	axis_x,
	input	wire [10:0] axis_y,
	
	// vga输出彩条
	output	reg			hs_o,
	output	reg			vs_o,
	output	reg [15:0]	rgb_o
);

// 产生彩色条
always@(posedge clk)
begin
	if(axis_en)
	begin
		if(axis_x < X*1/8)
			rgb_o <= {5'b11111,6'b111111,5'b11111};
		else if(axis_x < X*2/8)
			rgb_o <= {5'b11111,6'b111111,5'b00000};
		else if(axis_x < X*3/8)
			rgb_o <= {5'b11111,6'b000000,5'b11111};
		else if(axis_x < X*4/8)
			rgb_o <= {5'b11111,6'b000000,5'b00000};
		else if(axis_x < X*5/8)
			rgb_o <= {5'b00000,6'b111111,5'b11111};
		else if(axis_x < X*6/8)
			rgb_o <= {5'b00000,6'b111111,5'b00000};
		else if(axis_x < X*7/8)
			rgb_o <= {5'b00000,6'b000000,5'b11111};
		else if(axis_x < X*8/8)
			rgb_o <= {5'b00000,6'b000000,5'b00000};
	end
end

always@(posedge clk)
begin
	hs_o <= hs_i;
	vs_o <= vs_i;
end

endmodule
module buttons_led
#(
	parameter N        = 5,  //N is button number
	parameter CNT_20MS = 19'h75601//ÏµÍ³Ê±ÖÓ24MHz£¬ÒªÑÓÊ±20ms×óÓÒÊ±¼ä
)
(
	input  wire        		clk_24m,
	input  wire [N-1:0]  	btn,
	output reg  [15:0] 		led
);

wire       rst_n;
wire [4:0] key_pulse;

debounce
#(
	.N          (N          ),
	.CNT_20MS   (CNT_20MS	)
)
ux_btn
(
	.clk		(clk_24m	),
	.rst_n		(rst_n		),
	.key		(btn		),
	.key_pulse	(key_pulse	)
);

rst_n ux_rst
(
	.clk		(clk_24m	),
	.rst_n		(rst_n		)
);

//led off/on logic
always@(posedge clk_24m  or  negedge rst_n)
begin
    if(!rst_n) 
		        led[15:0]  <= 16'hFFFF;
	else if(key_pulse[0])
		        led[2:0]   <= ~led[2:0];
	else if(key_pulse[1])
		        led[5:3]   <= ~led[5:3];
	else if(key_pulse[2])
		        led[8:6]   <= ~led[8:6];
	else if(key_pulse[3])
		        led[11:9]  <= ~led[11:9];
	else if(key_pulse[4])
		        led[15:12] <= ~led[15:12];		      
	else
                led        <= led;
end    

endmodule
module debounce 
#(
	parameter  N         =  1,
	parameter  CNT_20MS  =  19'h75601//ÏµÍ³Ê±ÖÓ24MHz£¬ÒªÑÓÊ±20ms×óÓÒÊ±¼ä
)
(
	input	wire         clk,
	input	wire         rst_n,
	// key
	input   wire [N-1:0] key,
	output	wire [N-1:0] key_pulse
); 
  
reg [18:0]	cnt; //²úÉúÑÓÊ±ËùÓÃµÄ¼ÆÊýÆ÷£¬ÏµÍ³Ê±ÖÓ24MHz£¬ÒªÑÓÊ±20ms×óÓÒÊ±¼ä   

always@(posedge clk or negedge rst_n)
begin
     if(!rst_n)
          cnt <= 0;
     else if(cnt == CNT_20MS)
          cnt <= 0;
     else
          cnt <= cnt + 1'h1;
end  

reg [N-1:0] key_sec_pre;                
reg [N-1:0] key_sec;                      

always@(posedge clk  or  negedge rst_n)
begin
     if(!rst_n) 
         key_sec <= {N{1'b1}};                
     else if(cnt == CNT_20MS)
         key_sec <= key;  
end

always@(posedge clk  or  negedge rst_n)
begin
     if(!rst_n)
         key_sec_pre <= {N{1'b1}};
     else                   
         key_sec_pre <= key_sec;             
end  
    
assign  key_pulse = ~key_sec & key_sec_pre ;     
 
endmodule
module rst_n
(
	input	wire	clk,
	output	reg		rst_n
);

reg[3:0] cnt;

always@(posedge clk)
begin
	if(cnt == 4'hf)
		cnt <= cnt;
	else
		cnt <= cnt + 1'b1;
end

always@(posedge clk)
begin
	if(cnt == 4'hf)
		rst_n <= 1'b1;
	else
		rst_n <= 1'b0;
end

endmodule
module cmsdk_ahb_to_iop
// ----------------------------------------------------------------------------
// Port Definitions
// ----------------------------------------------------------------------------
  (// AHB Inputs
   input  wire                 HCLK,      // system bus clock
   input  wire                 HRESETn,   // system bus reset
   input  wire                 HSEL,      // AHB peripheral select
   input  wire                 HREADY,    // AHB ready input
   input  wire  [1:0]          HTRANS,    // AHB transfer type
   input  wire  [2:0]          HSIZE,     // AHB hsize
   input  wire                 HWRITE,    // AHB hwrite
   input  wire [11:0]          HADDR,     // AHB address bus
   input  wire [31:0]          HWDATA,    // AHB write data bus

   // IOP Inputs
   input wire [31:0]           IORDATA,    // I/0 read data bus

   // AHB Outputs
   output wire                 HREADYOUT, // AHB ready output to S->M mux
   output wire                 HRESP,     // AHB response
   output wire [31:0]          HRDATA,

   // IOP Outputs
   output reg                  IOSEL,      // Decode for peripheral
   output reg  [11:0]          IOADDR,     // I/O transfer address
   output reg                  IOWRITE,    // I/O transfer direction
   output reg  [1:0]           IOSIZE,     // I/O transfer size
   output reg                  IOTRANS,    // I/O transaction
   output wire [31:0]          IOWDATA);   // I/O write data bus

  // ----------------------------------------------------------
  // Read/write control logic
  // ----------------------------------------------------------

  // registered HSEL, update only if selected to reduce toggling
  always @(posedge HCLK or negedge HRESETn)
  begin
    if (~HRESETn)
      IOSEL <= 1'b0;
    else
      IOSEL <= HSEL & HREADY;
  end

  // registered address, update only if selected to reduce toggling
  always @(posedge HCLK or negedge HRESETn)
  begin
    if (~HRESETn)
      IOADDR <= {12{1'b0}};
    else
      IOADDR <= HADDR[11:0];
  end

  // Data phase write control
  always @(posedge HCLK or negedge HRESETn)
  begin
    if (~HRESETn)
      IOWRITE <= 1'b0;
    else
      IOWRITE <= HWRITE;
  end

  // registered hsize, update only if selected to reduce toggling
  always @(posedge HCLK or negedge HRESETn)
  begin
    if (~HRESETn)
      IOSIZE <= {2{1'b0}};
    else
      IOSIZE <= HSIZE[1:0];
  end

  // registered HTRANS, update only if selected to reduce toggling
  always @(posedge HCLK or negedge HRESETn)
  begin
    if (~HRESETn)
      IOTRANS <= 1'b0;
    else
      IOTRANS <= HTRANS[1];
  end

  assign IOWDATA   = HWDATA;
  assign HRDATA    = IORDATA;
  assign HREADYOUT = 1'b1;
  assign HRESP     = 1'b0;

endmodule
module cmsdk_clkreset(
  output wire CLK,
  output wire NRST);

  reg clock_q = 1'b0;
  reg reset_n_q = 1'b0;

  initial
    begin
      #10 clock_q <= 1'b1;
      #100 reset_n_q <= 1'b1;
    end

  always @(clock_q)
      #10 clock_q <= ~clock_q;

  assign CLK = clock_q;
  assign NRST = reset_n_q;

endmodule
module AHB2MEM
   #(parameter MEMWIDTH = 12)               // Size = 4KB
   (
   input wire           HSEL,
   input wire           HCLK,
   input wire           HRESETn,
   input wire           HREADY,
   input wire    [31:0] HADDR,
   input wire     [1:0] HTRANS,
   input wire           HWRITE,
   input wire     [2:0] HSIZE,
   input wire    [31:0] HWDATA,
   output wire          HREADYOUT,
   output reg    [31:0] HRDATA,
   output wire          HRESP
   );

   assign HREADYOUT = 1'b1; // Always ready
   assign HRESP     = 1'b0;
   // Memory Array
   reg  [31:0] memory[0:(2**(MEMWIDTH-2)-1)];

   // Registers to store Adress Phase Signals
   reg  [31:0] hwdata_mask;
   reg         we;
   reg  [31:0] buf_hwaddr;

   // Sample the Address Phase   
   always @(posedge HCLK or negedge HRESETn)
   begin
      if(!HRESETn)
      begin
         we <= 1'b0;
         buf_hwaddr <= 32'h0;
      end
      else
         if(HREADY)
         begin
            we <= HSEL & HWRITE & HTRANS[1];
            buf_hwaddr <= HADDR;
   
            casez (HSIZE[1:0])
               2'b1?: hwdata_mask <=  32'hFFFFFFFF;                        // Word write
               2'b01: hwdata_mask <= (32'h0000FFFF << (16 * HADDR[1]));    // Halfword write
               2'b00: hwdata_mask <= (32'h000000FF << (8 * HADDR[1:0]));   // Byte write
            endcase
          end
   end
   
   // Read and Write Memory
   always @ (posedge HCLK)
   begin
      if(we) 
         memory[buf_hwaddr[MEMWIDTH:2]] <= (HWDATA & hwdata_mask) | (HRDATA & ~hwdata_mask);
         
      HRDATA = memory[HADDR[MEMWIDTH:2]];
   end

endmodule
module cmsdk_mcu_stclkctrl #(
  // Ratio between FCLK and SysTck reference clock
  parameter DIV_RATIO = 18'd01000,

  // Divide by half for each phase
  parameter DIVIDER_RELOAD = (DIV_RATIO>>1)-1
 )
 (
  input  wire        FCLK,      // Free running clock
  input  wire        SYSRESETn, // System reset

  output wire        STCLKEN,   // SysTick clock
  output wire [25:0] STCALIB    // SysTick calibration
  );

  reg     [17:0] reg_clk_divider;
  reg            reg_stclken;

  assign STCALIB[25] = 1'b0; // NoRef - reference clock provided
  assign STCALIB[24] = 1'b1; // Skew - reference info not available
  assign STCALIB[23:0] = {24{1'b0}}; // 10 ms value  set to 0, indicate this value is not used

  // Divider
  wire [17:0] reg_clk_div_min1 = reg_clk_divider - {{17{1'b0}}, 1'b1};
  always @(posedge FCLK or negedge SYSRESETn)
  begin
  if (~SYSRESETn)
    reg_clk_divider <= {18{1'b0}};
  else
    begin
    if (|reg_clk_divider)
      reg_clk_divider <= reg_clk_div_min1[17:0];
    else
      reg_clk_divider <= DIVIDER_RELOAD[17:0];
    end
  end

  // Toggle register
  always @(posedge FCLK or negedge SYSRESETn)
  begin
  if (~SYSRESETn)
    reg_stclken <= 1'b0;
  else
    begin
    if (reg_clk_divider==18'h00000)
      reg_stclken <= ~reg_stclken;
    end
  end

  // Connect to top level
  assign STCLKEN = reg_stclken;

endmodule
module M0demo(
    input  wire          XTAL1, //
    output wire          XTAL2, //
    input  wire          NRST,  //
    output  wire  [15:0]  P0,
    //inout  wire  [15:0]  P1,
    
    input  wire          nTRST,
    input  wire          TDI,
    output wire          TDO,
    inout  wire          SWDIOTMS,
    input  wire          SWCLKTCK,
    
    inout  wire  [7:0]   b_pad_gpio_porta,

    input  wire          uart0_rxd,
    output wire          uart0_txd,
    output wire          uart0_txen


);
    wire XTAL1_wire;

  parameter BE              = 0;   // Big or little endian

  parameter BKPT            = 4;   // Number of breakpoint comparators
  parameter DBG             = 1;   // Debug configuration
  parameter NUMIRQ          = 32;  // NUM of IRQ
  parameter SMUL            = 0;   // Multiplier configuration
  parameter SYST            = 1;   // SysTick
  parameter WIC             = 1;   // Wake-up interrupt controller support
  parameter WICLINES        = 34;  // Supported WIC lines
  parameter WPT             = 2;   // Number of DWT comparators

 // --------------------------------------------------------------------------------
 // Cortex-M0/Cortex-M0+ Microcontroller
 // --------------------------------------------------------------------------------

  cmsdk_mcu
   #(.BE               (BE),
     .BKPT             (BKPT),          // Number of breakpoint comparators
     .DBG              (DBG),           // Debug configuration
     .NUMIRQ           (NUMIRQ),        // NUMIRQ
     .SMUL             (SMUL),          // Multiplier configuration
     .SYST             (SYST),          // SysTick
     .WIC              (WIC),           // Wake-up interrupt controller support
     .WICLINES         (WICLINES),      // Supported WIC lines
     .WPT              (WPT)            // Number of DWT comparators
   )
   u_cmsdk_mcu (
  .XTAL1      (XTAL1_wire),  // input
  .XTAL2      (XTAL2),  // output
  .NRST       (NRST),   // active low reset
  .P0         (P0),
  //.P1         (P1),
  .nTRST      (nTRST),  // Not needed if serial-wire debug is used
  .TDI        (TDI),    // Not needed if serial-wire debug is used
  .TDO        (TDO),    // Not needed if serial-wire debug is used
  .TMS        (SWDIOTMS),
  .TCK        (SWCLKTCK),
  
  .b_pad_gpio_porta (b_pad_gpio_porta),
                
  .uart0_rxd        (uart0_rxd),
  .uart0_txd        (uart0_txd),
  .uart0_txen       (uart0_txen)
  );
  


M0clkpll u_M0clkpll(
	.refclk	 (XTAL1    ),
	.clk0_out (XTAL1_wire)
);
  
  
  
endmodule
module M0clkpll  // al_ip/M0clkpll.v(22)
  (
  refclk,
  reset,
  stdby,
  clk0_out,
  extlock
  );

  input refclk;  // al_ip/M0clkpll.v(28)
  input reset;  // al_ip/M0clkpll.v(29)
  input stdby;  // al_ip/M0clkpll.v(30)
  output clk0_out;  // al_ip/M0clkpll.v(32)
  output extlock;  // al_ip/M0clkpll.v(31)

  wire clk0_buf;  // al_ip/M0clkpll.v(34)

  EG_PHY_GCLK bufg_feedback (
    .clki(clk0_buf),
    .clko(clk0_out));  // al_ip/M0clkpll.v(36)
  EG_PHY_CONFIG #(
    .DONE_PERSISTN("ENABLE"),
    .INIT_PERSISTN("ENABLE"),
    .JTAG_PERSISTN("DISABLE"),
    .PROGRAMN_PERSISTN("DISABLE"))
    config_inst ();
  EG_PHY_PLL #(
    .CLKC0_CPHASE(124),
    .CLKC0_DIV(125),
    .CLKC0_DIV2_ENABLE("DISABLE"),
    .CLKC0_ENABLE("ENABLE"),
    .CLKC0_FPHASE(0),
    .CLKC1_CPHASE(1),
    .CLKC1_DIV(1),
    .CLKC1_DIV2_ENABLE("DISABLE"),
    .CLKC1_ENABLE("DISABLE"),
    .CLKC1_FPHASE(0),
    .CLKC2_CPHASE(1),
    .CLKC2_DIV(1),
    .CLKC2_DIV2_ENABLE("DISABLE"),
    .CLKC2_ENABLE("DISABLE"),
    .CLKC2_FPHASE(0),
    .CLKC3_CPHASE(1),
    .CLKC3_DIV(1),
    .CLKC3_DIV2_ENABLE("DISABLE"),
    .CLKC3_ENABLE("DISABLE"),
    .CLKC3_FPHASE(0),
    .CLKC4_CPHASE(1),
    .CLKC4_DIV(1),
    .CLKC4_DIV2_ENABLE("DISABLE"),
    .CLKC4_ENABLE("DISABLE"),
    .CLKC4_FPHASE(0),
    .DERIVE_PLL_CLOCKS("DISABLE"),
    .DPHASE_SOURCE("DISABLE"),
    .DYNCFG("DISABLE"),
    .FBCLK_DIV(1),
    .FEEDBK_MODE("NORMAL"),
    .FEEDBK_PATH("CLKC0_EXT"),
    .FIN("24.000"),
    .FREQ_LOCK_ACCURACY(2),
    .GEN_BASIC_CLOCK("DISABLE"),
    .GMC_GAIN(6),
    .GMC_TEST(14),
    .ICP_CURRENT(3),
    .IF_ESCLKSTSW("DISABLE"),
    .INTFB_WAKE("DISABLE"),
    .KVCO(6),
    .LPF_CAPACITOR(3),
    .LPF_RESISTOR(2),
    .NORESET("DISABLE"),
    .ODIV_MUXC0("DIV"),
    .ODIV_MUXC1("DIV"),
    .ODIV_MUXC2("DIV"),
    .ODIV_MUXC3("DIV"),
    .ODIV_MUXC4("DIV"),
    .PLLC2RST_ENA("DISABLE"),
    .PLLC34RST_ENA("DISABLE"),
    .PLLMRST_ENA("DISABLE"),
    .PLLRST_ENA("ENABLE"),
    .PLL_LOCK_MODE(0),
    .PREDIV_MUXC0("VCO"),
    .PREDIV_MUXC1("VCO"),
    .PREDIV_MUXC2("VCO"),
    .PREDIV_MUXC3("VCO"),
    .PREDIV_MUXC4("VCO"),
    .REFCLK_DIV(3),
    .REFCLK_SEL("INTERNAL"),
    .STDBY_ENABLE("ENABLE"),
    .STDBY_VCO_ENA("DISABLE"),
    .SYNC_ENABLE("DISABLE"),
    .VCO_NORESET("DISABLE"))
    pll_inst (
    .daddr(6'b000000),
    .dclk(1'b0),
    .dcs(1'b0),
    .di(8'b00000000),
    .dwe(1'b0),
    .fbclk(clk0_out),
    .psclk(1'b0),
    .psclksel(3'b000),
    .psdown(1'b0),
    .psstep(1'b0),
    .refclk(refclk),
    .reset(reset),
    .stdby(stdby),
    .clkc({open_n47,open_n48,open_n49,open_n50,clk0_buf}),
    .extlock(extlock));  // al_ip/M0clkpll.v(59)

endmodule
module cmsdk_ahb_upsizer64 (
  input  wire        HCLK,       // Clock
  input  wire        HRESETn,    // Reset

  // AHB connection to master
  input  wire        HSELS,
  input  wire [31:0] HADDRS,
  input  wire  [1:0] HTRANSS,
  input  wire  [2:0] HSIZES,
  input  wire        HWRITES,
  input  wire        HREADYS,
  input  wire  [3:0] HPROTS,
  input  wire  [2:0] HBURSTS,
  input  wire        HMASTLOCKS,
  input  wire [31:0] HWDATAS,

  output wire        HREADYOUTS,
  output wire        HRESPS,
  output wire [31:0] HRDATAS,

  // AHB output master port : 64 bit data bus interface
  output wire        HSELM,
  output wire [31:0] HADDRM,
  output wire  [1:0] HTRANSM,
  output wire  [2:0] HSIZEM,
  output wire        HWRITEM,
  output wire        HREADYM,
  output wire  [3:0] HPROTM,
  output wire  [2:0] HBURSTM,
  output wire        HMASTLOCKM,
  output wire [63:0] HWDATAM,

  input  wire        HREADYOUTM,
  input  wire        HRESPM,
  input  wire [63:0] HRDATAM);

  // ----------------------------------------
  // Internal wires declarations
   reg          hrdata_sel_reg;   // select the higher or lower 32
                            // bits data send from slave to master

  //-----------------------------------------------------------
  //Module logic start
  //----------------------------------------------------------

  // Data select signal
  always @(posedge HCLK or negedge HRESETn)
    begin
    if (~HRESETn)
      hrdata_sel_reg <= 1'b0; // by default lower 32 bits are selected
    else if (HREADYS & HSELS & HTRANSS[1])
      hrdata_sel_reg <= HADDRS[2];
    end

  // Outputs
  // The master and slave signals are connected directly, except data bus.
  // This arrangement allows a modular design integration in tools like
  // AMBA Designer
    // from slave to master
   assign HREADYOUTS = HREADYOUTM;
   assign HRESPS     = HRESPM;
   assign HRDATAS    = hrdata_sel_reg ? HRDATAM[63:32] : HRDATAM[31:0];

    // from master to slave
   assign HSELM      = HSELS;
   assign HADDRM     = HADDRS;
   assign HTRANSM    = HTRANSS;
   assign HREADYM    = HREADYS;
   assign HSIZEM     = HSIZES;
   assign HWRITEM    = HWRITES;
   assign HPROTM     = HPROTS;
   assign HBURSTM    = HBURSTS;
   assign HMASTLOCKM = HMASTLOCKS;
   assign HWDATAM    = {HWDATAS,HWDATAS}; // Replicate HWDATAS on lower and
                                          // upper 32 bits

  //-----------------------------------------------------------
  //Module logic end
  //----------------------------------------------------------

endmodule
module cmsdk_irq_sync (
  input  wire  RSTn,
  input  wire  CLK,
  input  wire  IRQIN,
  output wire  IRQOUT);

  reg  [2:0] sync_reg;
  wire [2:0] nxt_sync_reg;

  assign nxt_sync_reg = {sync_reg[1:0],IRQIN};

  always @(posedge CLK or negedge RSTn)
    begin
    if (~RSTn)
      sync_reg <= 3'b000;
    else
      sync_reg <= nxt_sync_reg;
    end

  // Only consider valid if it is high for two cycles
  assign   IRQOUT  = sync_reg[2] & sync_reg[1];

endmodule
module cmsdk_apb4_eg_slave_interface #(
  // parameter for address width
  parameter ADDRWIDTH = 12)
 (
  // IO declaration

  input  wire                    pclk,     // pclk
  input  wire                    presetn,  // reset

  // apb interface inputs
  input  wire                    psel,
  input  wire [ADDRWIDTH-1:0]    paddr,
  input  wire                    penable,
  input  wire                    pwrite,
  input  wire [31:0]             pwdata,
  input  wire [3:0]              pstrb,

  // apb interface outputs
  output wire [31:0]             prdata,
  output wire                    pready,
  output wire                    pslverr,

  //Register interface
  output wire [ADDRWIDTH-1:0]    addr,
  output wire                    read_en,
  output wire                    write_en,
  output wire [3:0]              byte_strobe,
  output wire [31:0]             wdata,
  input  wire [31:0]             rdata);


 //--------------------------
  // ----------------------------------------------------
 // module logic start
 //------------------------------------------------------------------------------

// APB interface
assign   pready  = 1'b1; //always ready. Can be customized to support waitstate if required.
assign   pslverr = 1'b0; //always OKAY. Can be customized to support error response if required.


// register read and write signal
assign  addr = paddr;
assign  read_en  = psel & (~pwrite); // assert for whole apb read transfer
assign  write_en = psel & (~penable) & pwrite; // assert for 1st cycle of write transfer
        // It is also possible to change the design to perform the write in the 2nd
        // APB cycle.   E.g.
        //   assign write_en = psel & penable & pwrite;
        // However, if the design generate waitstate, this expression will result
        // in write_en being asserted for multiple cycles.
assign  byte_strobe = pstrb;
assign  wdata       = pwdata;
assign  prdata      = rdata;

`ifdef ARM_APB_ASSERT_ON

 `include "std_ovl_defines.h"
  // ------------------------------------------------------------
  // Assertions
  // ------------------------------------------------------------

  // Check error response should not be generated if not selected
    assert_never
     #(`OVL_ERROR,
       `OVL_ASSERT,
       "Error! Should not generate error response if not selected")
     u_ovl_apb4_eg_slave_response_illegal
     (.clk        (pclk),
      .reset_n    (presetn),
      .test_expr  (pslverr & pready & (~psel))
      );

`endif
 //------------------------------------------------------------------------------
 // module logic end
 //------------------------------------------------------------------------------

endmodule
module cmsdk_ahb_fileread_funnel (
 // Clock and Reset
 input  wire        HCLK,
 input  wire        HRESETn,
 // Interface to AHB
 input  wire        HADDR2S,
 input  wire [63:0] HWDATAS,
 input  wire        HREADYS,
 output wire [63:0] HRDATAS,
 // Interface to slave
 output reg  [31:0] HWDATAM,
 input  wire [31:0] HRDATAM);

// -----------------------------------------------------------------------------
// Signal Declarations
// -----------------------------------------------------------------------------

reg        haddr2s_reg;       // Delayed version of address bit2

// =============================================================================
// Beginning of main verilog code
// =============================================================================

//------------------------------------------------------------------------------
// Generate Delayed version of HADDR2S
//------------------------------------------------------------------------------
always@(posedge HCLK or negedge HRESETn)
  begin : p_haddr2s_reg
    if (HRESETn == 1'b0)
      haddr2s_reg <= 1'b0;
    else
      begin
        if (HREADYS == 1'b1)
        haddr2s_reg <= HADDR2S;
      end
  end // block: p_haddr2s_reg

// -----------------------------------------------------------------------------
// Write Data MUX
// -----------------------------------------------------------------------------
// Note: To support Big-Endian systems the polarity of the HWDATAM MUX should be
// reversed.

always@(haddr2s_reg or HWDATAS)
  begin : p_write_mux
    if (haddr2s_reg == 1'b0)
      HWDATAM = HWDATAS[31:0];
    else
      HWDATAM = HWDATAS[63:32];
  end // block: p_write_mux

// -----------------------------------------------------------------------------
// Read Data bus
// -----------------------------------------------------------------------------
  assign HRDATAS = {HRDATAM,HRDATAM};


endmodule
module cmsdk_ahb_fileread_master64 #(

  parameter  InputFileName = "filestim.m2d",  // stimulus data file name
  parameter  MessageTag    = "FileReader:",   // tag on each FileReader message
  parameter  StimArraySize = 5000)            // stimulus data array size:
                                              //  should be large enough to hold
                                              //  entire stimulus data file
 (
  // system ports
  input  wire         HCLK,          //  system clock
  input  wire         HRESETn,       //  system reset

  // AHB ports
  input  wire         HREADY,        //  slave ready signal
  input  wire         HRESP,         //  slave response bus
  input  wire [63:0]  HRDATA,        //  data, slave to master
  input  wire         EXRESP,        //  Exclusive response (tie low if not used)

  output wire [1:0]   HTRANS,        //  transfer type
  output wire [2:0]   HBURST,        //  burst type
  output wire [3:0]   HPROT,         //  transfer protection
  output wire         EXREQ,         //  Exclusive access request
  output wire [1:0]   MEMATTR,       //  Memory attribute
  output wire [2:0]   HSIZE,         //  transfer size
  output wire         HWRITE,        //  transfer direction
  output wire         HMASTLOCK,     //  transfer is locked
  output wire [31:0]  HADDR,         //  transfer address
  output wire [63:0]  HWDATA,        //  data, master to slave

  output wire [31:0]  LINENUM);      //  line number in stimulus file

  // Internal AHB-Lite Bus Signals
  wire   [2:0]   hresp_core;    //  slave response
  wire   [5:0]   hprot_core;    //  transfer protection

//------------------------------------------------------------------------------
// structural
//------------------------------------------------------------------------------

  // Instance of AHB-Lite File Reader connected to internal AHB-Lite system
  cmsdk_ahb_filereadcore
    #(.input_filename(InputFileName), .message_tag(MessageTag), .stim_array_size(StimArraySize))
    u_ahb_filereadcore    (

    .HCLK           (HCLK),
    .HRESETn        (HRESETn),

    .HREADY         (HREADY),
    .HRESP          (hresp_core),
    .HRDATA         (HRDATA),

    .HTRANS         (HTRANS),
    .HBURST         (HBURST),
    .HPROT          (hprot_core),
    .HSIZE          (HSIZE),
    .HWRITE         (HWRITE),
    .HMASTLOCK      (HMASTLOCK),
    .HADDR          (HADDR),
    .HWDATA         (HWDATA),
    .HUNALIGN       (),
    .HBSTRB         (),
    .LINENUM        (LINENUM)
    );

  // Convert internal versions of port signals
  assign HPROT          = hprot_core[3:0];
  assign EXREQ          = hprot_core[5];
  assign MEMATTR        = {1'b0, hprot_core[4]};

  assign hresp_core     = {EXRESP, 1'b0,HRESP};       // Drive unused bit of hresp_core

endmodule
module cmsdk_clock_gate #(
  // ---------------------------------------------------------------------------
  // Parameters
  // ---------------------------------------------------------------------------
  parameter CLKGATE_PRESENT = 0)
 (
  // ---------------------------------------------------------------------------
  // Port Definitions
  // ---------------------------------------------------------------------------

  input  wire CLK,
  input  wire CLKENABLE,
  input  wire DISABLEG,

  output wire GATEDCLK);

  //----------------------------------------------------------------------------
  // Overview
  //----------------------------------------------------------------------------
  //
  // The mcu_clock_gate block is used to abstract the high level clock gating
  // function used for the primary clocks in the macrocell.
  //
  // A functional clock enable <CLKENABLE> is combined with
  // a scanenable/global disable signal to provide the gating term. This is
  // then latched prior to gating with the main clock CLK.
  //
  // A clock gating cell can be instantiated manually by removing the RTL
  // equivalent section and instantiating the appropriate cell.

  // ---------------------------------------------------------------------------
  // Signal Declarations
  // ---------------------------------------------------------------------------
  wire   i_clk;
  wire   clk_en;
  reg    clk_en_t2;
  wire   i_gated_clk;
  wire   mst_clk_en;
  wire   mst_disable;

  //----------------------------------------------------------------------------
  // Clock gate removal - do not alter this section
  //----------------------------------------------------------------------------
  assign GATEDCLK     = (CLKGATE_PRESENT != 0) ? i_gated_clk : 1'b0;
  assign mst_clk_en   = (CLKGATE_PRESENT != 0) ? CLKENABLE : 1'b0;
  assign mst_disable  = (CLKGATE_PRESENT != 0) ? DISABLEG  : 1'b0;
  assign i_clk        = (CLKGATE_PRESENT != 0) ? CLK       : 1'b0;

  //----------------------------------------------------------------------------
  // Beginning of main code
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  // RTL equivalent - remove this section if you wish to use a real cell
  //----------------------------------------------------------------------------
  assign clk_en = mst_clk_en | mst_disable;

  always @(i_clk or clk_en)
    if (i_clk == 1'b0)
      clk_en_t2 <= clk_en;

  assign i_gated_clk = i_clk & clk_en_t2;

  //----------------------------------------------------------------------------
  // Instantiated clock gating cell - instantiate appropriate cell here if
  // replacing RTL equivalent section
  //----------------------------------------------------------------------------
  // For example:
  //  TLATNTSCAX12 ICGCell (.ECK (i_gated_clk), .E (mst_clk_en), .SE (mst_disable), .CK (iCLK));

endmodule
module cmsdk_ahb_to_apb_async_syn (
// --------------------------------------------------------------------------
// Port Definitions
// --------------------------------------------------------------------------
  input  wire      clk,
  input  wire      resetn,

  input  wire      enable,
  input  wire      d_in,

  output wire      d_out);

  // --------------------------------------------------------------------------
  // Internal wires
  // --------------------------------------------------------------------------
  reg         sync_reg_1;
  reg         sync_reg_2;

  // --------------------------------------------------------------------------
  // Start of main code
  // --------------------------------------------------------------------------

  // Double flip-flop syncrhonizer
  always @(posedge clk or negedge resetn)
  begin
  if (~resetn)
    begin
    sync_reg_1 <= 1'b0;
    sync_reg_2 <= 1'b0;
    end
  else if (enable)
    begin
    sync_reg_1 <= d_in;
    sync_reg_2 <= sync_reg_1;
    end
  end

  assign  d_out = sync_reg_2;

endmodule
module cmsdk_apb3_eg_slave_interface #(
  // parameter for address width
  parameter ADDRWIDTH = 12)
 (
  // IO declaration

  input  wire                    pclk,     // pclk
  input  wire                    presetn,  // reset

  // apb interface inputs
  input  wire                    psel,
  input  wire [ADDRWIDTH-1:0]    paddr,
  input  wire                    penable,
  input  wire                    pwrite,
  input  wire [31:0]             pwdata,

  // apb interface outputs
  output wire [31:0]             prdata,
  output wire                    pready,
  output wire                    pslverr,

  // Data register read/write interface
  output wire [ADDRWIDTH-1:0]    addr,
  output wire                    read_en,
  output wire                    write_en,
  output wire [31:0]             wdata,
  input  wire [31:0]             rdata);

 //------------------------------------------------------------------------------
 // module logic start
 //------------------------------------------------------------------------------

// APB interface
assign   pready  = 1'b1; //always ready. Can be customized to support waitstate if required.
assign   pslverr = 1'b0; //alwyas OKAY. Can be customized to support error response if required.


// register read and write signal
assign  addr = paddr;
assign  read_en  = psel & (~pwrite); // assert for whole apb read transfer
assign  write_en = psel & (~penable) & pwrite; // assert for 1st cycle of write transfer
        // It is also possible to change the design to perform the write in the 2nd
        // APB cycle.   E.g.
        //   assign write_en = psel & penable & pwrite;
        // However, if the design generate waitstate, this expression will result
        // in write_en being asserted for multiple cycles.
assign  wdata       = pwdata;
assign  prdata      = rdata;


`ifdef ARM_APB_ASSERT_ON

 `include "std_ovl_defines.h"
  // ------------------------------------------------------------
  // Assertions
  // ------------------------------------------------------------

  // Check error response should not be generated if not selected
    assert_never
     #(`OVL_ERROR,
       `OVL_ASSERT,
       "Error! Should not generate error response if not selected")
     u_ovl_apb3_eg_slave_response_illegal
     (.clk        (pclk),
      .reset_n    (presetn),
      .test_expr  (pslverr & pready & (~psel))
      );

`endif

 //------------------------------------------------------------------------------
 // module logic end
 //------------------------------------------------------------------------------

endmodule
module cmsdk_ahb_to_ahb_apb_async_launch #(
      parameter WIDTH = 32
   ) (
      input  wire             CLK,
      input  wire             RSTn,
      input  wire             EN,
      input  wire [WIDTH-1:0] D,
      output wire [WIDTH-1:0] Q
   );

   // --------
   // Clock enabled D-type register.

   reg [WIDTH-1:0] q_q;

   always @(posedge CLK or negedge RSTn)
      if(~RSTn)
         q_q <= 1'b0;
      else if(EN)
         q_q <= D;

   assign Q = q_q;

endmodule
module cmsdk_ahb_to_ahb_apb_async_synchronizer (
      input  wire CLK,
      input  wire D,
      output wire Q
   );

   reg [1:0] q_q;

   always @(posedge CLK)
      q_q <= {q_q[0], D};

   assign Q = q_q[1];

endmodule
module cmsdk_ahb_to_ahb_apb_async_sample_and_hold #(
      parameter WIDTH = 32
   ) (
      input  wire             CLK,
      input  wire             EN,
      input  wire             MASK,
      input  wire [WIDTH-1:0] D,
      output wire [WIDTH-1:0] Q
   );

   // --------
   // Clock enabled D-type register.

   reg [WIDTH-1:0] q_q;

   always @(posedge CLK)
      if(EN)
         q_q <= D;

   // --------
   // Mask with hard AND gate.

   assign Q = q_q & {WIDTH{~MASK}};

endmodule
module dual_port_ram_sync
  #(
      parameter ADDR_WIDTH = 6,
      parameter DATA_WIDTH = 8
  )
  (
  input wire clk,
  input wire we,
  input wire [ADDR_WIDTH-1:0] addr_a,
  input wire [ADDR_WIDTH-1:0] addr_b,
  input wire [DATA_WIDTH-1:0] din_a,
  
  output wire [DATA_WIDTH-1:0] dout_a,
  output wire [DATA_WIDTH-1:0] dout_b
  );

  reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
  reg [ADDR_WIDTH-1:0] addr_a_reg;
  reg [ADDR_WIDTH-1:0] addr_b_reg;
  
  always @ (posedge clk)
  begin
    if(we)
      ram[addr_a] <= din_a;
    addr_a_reg <= addr_a;
    addr_b_reg <= addr_b;
  end
  
  assign dout_a = ram[addr_a_reg];
  assign dout_b = ram[addr_b_reg];
  
endmodule
module vga_image(
  input wire clk,
  input wire resetn,
  input wire video_on,
  input wire [9:0] pixel_x,
  input wire [9:0] pixel_y,
  input wire image_we,
`ifdef VGA_8BIT_IMAGE
  input wire [7:0] image_data,
`else
  input wire [11:0] image_data,
`endif  
  input wire [15:0] address,

  output wire image_on,
`ifdef VGA_8BIT_IMAGE
  output reg [7:0] image_rgb
`else
  output reg [11:0] image_rgb
`endif  
  );


`ifdef VGA_8BIT_IMAGE
  localparam PWIDTH  = 8;  // Pixel width
`else
  localparam PWIDTH  = 12;
`endif

  wire [15:0] addr_r;
  wire [15:0] addr_w;
  wire [PWIDTH-1:0] din;
  wire [PWIDTH-1:0] dout;

  reg [15:0] address_reg;
  reg [2:0] u3;
  
  //buffer address
  always @(posedge clk)
    address_reg <= address;

 dual_port_ram_sync
  #(.ADDR_WIDTH(16), .DATA_WIDTH(PWIDTH))
  u_image_ram
  ( .clk(clk),
    .we(image_we),
    .addr_a(addr_w),
    .addr_b(addr_r),
    .din_a(din),
    .dout_a(),
    .dout_b(dout)
  );
  

  assign addr_w = address_reg[15:0];
  assign din = image_data;
  
  
  //assign addr_r = {pixel_y[7:0], ~pixel_x[7], pixel_x[6:0]}; //offset x address by -128
  //assign addr_r = {~pixel_y[5],pixel_y[4:0], pixel_x[8:0]}; //offset x address by -128
  //assign addr_r = pixel_y[5:0] * 12'h280 + pixel_x[9:0];
  
  always@*
  begin
    if(pixel_y[7:5] == 3'b011)
        u3 = 3'b000;
    else if(pixel_y[7:5] == 3'b100)
        u3 = 3'b001;
    else if(pixel_y[7:5] == 3'b101)
        u3 = 3'b010;
    else if(pixel_y[7:5] == 3'b110)
        u3 = 3'b011;
    else
        u3 = 3'b100;
    end

  assign addr_r = {u3[1:0],pixel_y[4:0], pixel_x[8:0]}; //offset x address by -128
  
  //image on only in top right
  assign image_on = ((pixel_y[9:8] == 2'b01) && (u3[2] == 1'b0) && (pixel_x[9] == 1'b0));
  
  //image output
  always @*
  if(~image_on || ~video_on)
    image_rgb = {PWIDTH{1'b0}};
  else
    image_rgb = dout;

endmodule
module vga_sync(
  input  wire       clk,
  input  wire       resetn,
  input  wire       clk_cfg,  // 0 : clk=50MHz, 1 : clk=25MHz 
  output wire       hsync,
  output wire       vsync,
  output wire       video_on,
  output wire       p_tick,   // pixel clock
  output wire [9:0] pixel_x,
  output wire [9:0] pixel_y
);


  localparam HD = 640;  //horizontal display
  localparam HF = 48;   //h. front border
  localparam HB = 16;   //h. back border
  localparam HR = 96;   //h. retrace

  localparam VD = 480;  //vertical display
  localparam VF = 10;   //v. front border
  localparam VB = 33;   //v. back border
  localparam VR = 2;    //v. retrace



  reg       reg_px_div;
  wire      nxt_px_div;

  reg [9:0] h_count;
  reg [9:0] h_count_next;

  reg [9:0] v_count;
  reg [9:0] v_count_next;
  
  reg       hsync_reg;
  wire      hsync_next;
  
  reg       vsync_reg;
  wire      vsync_next;
  
 
  // Divide by 2 Counter to generate 25MHz clk 
  always @(posedge clk or negedge resetn)
  begin
    if(!resetn)
      reg_px_div <= 1'b0;
    else
      reg_px_div <= nxt_px_div;
  end
  
  assign nxt_px_div = ~reg_px_div;
  assign p_tick     = nxt_px_div | clk_cfg;

  // Horizontal Pixel Counter
  always @(posedge clk or negedge resetn)
  begin
    if(!resetn)
      h_count <= 10'b0;
    else
      h_count <= h_count_next;
  end

  always @*
  begin
    if(p_tick)
      if(h_count == (HD+HF+HB+HR-1))
        h_count_next = 10'b0;
      else
        h_count_next = h_count + 10'd1;
    else
      h_count_next = h_count;
  end

  assign pixel_x = h_count;

  // Vertical Pixel Counter
  always @(posedge clk or negedge resetn)
  begin
    if(!resetn)
      v_count <= 10'b0;
    else
      v_count <= v_count_next;
  end

  always @*
  begin
    if(p_tick & (h_count == (HD+HF+HB+HR-1)))
      if(v_count == (VD+VF+VB+VR-1))
        v_count_next = 10'b0;
      else
        v_count_next = v_count + 10'd1;
    else
      v_count_next = v_count;
  end

  assign pixel_y = v_count;

  //Horizontal and Vertical Sync
  always @(posedge clk, negedge resetn)
  begin
    if(!resetn)
      begin
        hsync_reg <= 1'b0;
        vsync_reg <= 1'b0;
      end
    else
      begin
        hsync_reg <= hsync_next;
        vsync_reg <= vsync_next;
      end
  end
  
  //If h_count and v_count are in the hsync range assert the signal
  assign hsync_next = ((h_count >= HD+HB) && (h_count <=HD+HB+HR-1));
  assign vsync_next = ((v_count >= VD+VB) && (v_count <=VD+VB+VR-1));

  assign hsync = hsync_reg;
  assign vsync = vsync_reg;

  //video_on signal
  assign video_on = ((h_count < HD) && (v_count < VD));

endmodule
module i2s_pulse_sync (
  input   wire     clk1,
  input   wire     rst1_n,

  input   wire     clk2,
  input   wire     rst2_n,

  input   wire     pulse_in,
  output  wire     pulse_out
  );


  reg     reg_pulse_latch;
  wire    nxt_pulse_latch;
  
  wire    sync_pulse_req;
  reg     last_pulse_req;
  wire    sync_pulse_ack;
  

  // Pulse latch
  assign nxt_pulse_latch = pulse_in | (reg_pulse_latch & ~sync_pulse_ack); 
  
  always @ (posedge clk1 or negedge rst1_n)
    if (!rst1_n)
       reg_pulse_latch  <= 1'b0;
    else
       reg_pulse_latch  <= nxt_pulse_latch;
     
  i2s_sync_cell u_sync_req (
    .clk    (clk2),
    .rst_n  (rst2_n),
    .din    (reg_pulse_latch),
    .dout   (sync_pulse_req)
    );
    
  always @ (posedge clk2 or negedge rst2_n)
    if (!rst2_n)
       last_pulse_req  <= 1'b0;
    else
       last_pulse_req  <= sync_pulse_req;

  // Pulse out is rising edge of sync_pulse_req
  assign pulse_out = sync_pulse_req & ~last_pulse_req;
  
  i2s_sync_cell u_sync_ack (
    .clk    (clk1),
    .rst_n  (rst1_n),
    .din    (sync_pulse_req),
    .dout   (sync_pulse_ack)
    );

endmodule
module i2s_async_dest #(
  parameter WIDTH=32
  )
  (
  input   wire               clk,
  input   wire               rst_n,

  input   wire  [WIDTH-1:0]  data_in,         // async input
  input   wire               data_in_valid,   // async input
  output  wire               data_in_ack,
  
  output  wire  [WIDTH-1:0]  data_out,
  output  wire               data_out_valid,
  input   wire               data_out_ack
  );
   
  reg  [WIDTH-1:0]  reg_data_out;  
  wire              sample_data;
  
  wire              data_in_valid_sync;

  reg               reg_buf_full; // Register for data_out_valid
  wire              nxt_buf_full;
  
  reg               reg_data_in_ack; // Register for data_in_ack
  wire              nxt_data_in_ack;

  // Sample the data when buffer is empty and data input request is valid
  assign sample_data  = (~reg_buf_full) & data_in_valid_sync & ~reg_data_in_ack;
  // Next state for buffer status
  assign nxt_buf_full = sample_data | (reg_buf_full & ~data_out_ack);

  // Register buffer full status
  always @(posedge clk or negedge rst_n)
  begin
  if (~rst_n)
    reg_buf_full <= 1'b0;
  else
    reg_buf_full <= nxt_buf_full;
  end

  // Acknowledge when data has been sampled
  // deassert ACK when data_in_valid_sync is low
  assign nxt_data_in_ack = sample_data | 
    (reg_data_in_ack & data_in_valid_sync);    
  
  // Register Data In ACK (back to source)
  always @(posedge clk or negedge rst_n)
  begin
  if (~rst_n)
    reg_data_in_ack <= 1'b0;
  else
    reg_data_in_ack <= nxt_data_in_ack;
  end

  always @(posedge clk or negedge rst_n)
  begin
  if (~rst_n)
    reg_data_out <= {WIDTH{1'b0}};
  else if (sample_data)
    reg_data_out <= data_in;
  end
  
  assign data_out       = reg_data_out;
  assign data_out_valid = reg_buf_full;
  assign data_in_ack    = reg_data_in_ack;

  //--------------------------------------------
  // Synchroniser

  i2s_sync_cell u_i2s_sync_cell (
    .clk    (clk),
    .rst_n  (rst_n),
    .din    (data_in_valid),
    .dout   (data_in_valid_sync)
  );  

endmodule
module i2s_sync_cell (
  input   wire     clk,
  input   wire     rst_n,
  input   wire     din,
  output  wire     dout
  );

  reg   sync1;
  reg   sync2;

  // synchroniser
  always @ (posedge clk or negedge rst_n)
    if (!rst_n)
      begin
       sync1  <= 1'b0;
       sync2  <= 1'b0;
      end
    else
      begin
        sync1 <= din;
        sync2 <= sync1;
      end
  
  assign dout = sync2;

endmodule
module i2s_async_src #(
  parameter WIDTH=32
  )
  (
  input   wire               clk,
  input   wire               rst_n,

  input   wire  [WIDTH-1:0]  data_in,
  input   wire               data_in_valid,
  output  wire               data_in_ack,
  
  output  wire  [WIDTH-1:0]  data_out,
  output  wire               data_out_valid,
  input   wire               data_out_ack    // async input
  );
  
  reg        [1:0]  reg_state;  
  // 00 - idle
  // 01 - data output, valid high, wait for ack to set
  // 10 - data output, valid low, wait for ack to clear
  reg        [1:0]  nxt_state;
  
  reg  [WIDTH-1:0]  reg_data_out;  
  wire              data_out_update;
  
  wire              data_out_ack_sync;

  always @(posedge clk or negedge rst_n)
  begin
  if (~rst_n)
    reg_state <= {2{1'b0}};
  else
    reg_state <= nxt_state;
  end

  always @(reg_state or data_in_valid or data_out_ack_sync)
  begin
  case (reg_state)
    2'b00: nxt_state = (data_in_valid) ? 2'b01 : 2'b00;
    2'b01: nxt_state = (data_out_ack_sync) ? 2'b10 : 2'b01;
    2'b10: nxt_state = (~data_out_ack_sync) ? 2'b00 : 2'b10;
    2'b11: nxt_state = 2'b00;
  endcase
  end
  
  assign data_out_update = (data_in_valid & (reg_state==2'b00));
  assign data_in_ack = data_out_update;
  assign data_out_valid = reg_state[0];
  
  always @(posedge clk or negedge rst_n)
  begin
  if (~rst_n)
    reg_data_out <= {WIDTH{1'b0}};
  else if (data_out_update)
    reg_data_out <= data_in;
  end
  
  assign data_out = reg_data_out;

  //--------------------------------------------
  // Synchroniser

  i2s_sync_cell u_i2s_sync_cell (
    .clk    (clk),
    .rst_n  (rst_n),
    .din    (data_out_ack),
    .dout   (data_out_ack_sync)
  );  

endmodule