dakies/OSS_Verilog huggingface dataset:
module top
(
  clk_i,
  reset_i,
  calibration_done_i,
  channel_active_i,
  in_v_i,
  in_data_i,
  in_yumi_o,
  in_v_o,
  in_data_o,
  in_yumi_i,
  out_me_v_i,
  out_me_data_i,
  out_me_ready_o,
  out_me_v_o,
  out_me_data_o,
  out_me_ready_i
);

  input [3:0] channel_active_i;
  input [3:0] in_v_i;
  input [63:0] in_data_i;
  output [3:0] in_yumi_o;
  output [3:0] in_v_o;
  output [63:0] in_data_o;
  input [3:0] in_yumi_i;
  input [3:0] out_me_v_i;
  input [63:0] out_me_data_i;
  output [3:0] out_me_ready_o;
  output [3:0] out_me_v_o;
  output [63:0] out_me_data_o;
  input [3:0] out_me_ready_i;
  input clk_i;
  input reset_i;
  input calibration_done_i;

  bsg_sbox
  wrapper
  (
    .channel_active_i(channel_active_i),
    .in_v_i(in_v_i),
    .in_data_i(in_data_i),
    .in_yumi_o(in_yumi_o),
    .in_v_o(in_v_o),
    .in_data_o(in_data_o),
    .in_yumi_i(in_yumi_i),
    .out_me_v_i(out_me_v_i),
    .out_me_data_i(out_me_data_i),
    .out_me_ready_o(out_me_ready_o),
    .out_me_v_o(out_me_v_o),
    .out_me_data_o(out_me_data_o),
    .out_me_ready_i(out_me_ready_i),
    .clk_i(clk_i),
    .reset_i(reset_i),
    .calibration_done_i(calibration_done_i)
  );


endmodule
module top
(
  clk_i,
  reset_i,
  ready_o,
  data_i,
  v_i,
  v_o,
  data_o,
  yumi_i
);

  input [15:0] data_i;
  output [15:0] data_o;
  input clk_i;
  input reset_i;
  input v_i;
  input yumi_i;
  output ready_o;
  output v_o;

  bsg_one_fifo
  wrapper
  (
    .data_i(data_i),
    .data_o(data_o),
    .clk_i(clk_i),
    .reset_i(reset_i),
    .v_i(v_i),
    .yumi_i(yumi_i),
    .ready_o(ready_o),
    .v_o(v_o)
  );


endmodule
module bsg_dff_en_width_p16_harden_p0
(
  clk_i,
  data_i,
  en_i,
  data_o
);

  input [15:0] data_i;
  output [15:0] data_o;
  input clk_i;
  input en_i;
  wire [15:0] data_o;
  reg data_o_15_sv2v_reg,data_o_14_sv2v_reg,data_o_13_sv2v_reg,data_o_12_sv2v_reg,
  data_o_11_sv2v_reg,data_o_10_sv2v_reg,data_o_9_sv2v_reg,data_o_8_sv2v_reg,
  data_o_7_sv2v_reg,data_o_6_sv2v_reg,data_o_5_sv2v_reg,data_o_4_sv2v_reg,data_o_3_sv2v_reg,
  data_o_2_sv2v_reg,data_o_1_sv2v_reg,data_o_0_sv2v_reg;
  assign data_o[15] = data_o_15_sv2v_reg;
  assign data_o[14] = data_o_14_sv2v_reg;
  assign data_o[13] = data_o_13_sv2v_reg;
  assign data_o[12] = data_o_12_sv2v_reg;
  assign data_o[11] = data_o_11_sv2v_reg;
  assign data_o[10] = data_o_10_sv2v_reg;
  assign data_o[9] = data_o_9_sv2v_reg;
  assign data_o[8] = data_o_8_sv2v_reg;
  assign data_o[7] = data_o_7_sv2v_reg;
  assign data_o[6] = data_o_6_sv2v_reg;
  assign data_o[5] = data_o_5_sv2v_reg;
  assign data_o[4] = data_o_4_sv2v_reg;
  assign data_o[3] = data_o_3_sv2v_reg;
  assign data_o[2] = data_o_2_sv2v_reg;
  assign data_o[1] = data_o_1_sv2v_reg;
  assign data_o[0] = data_o_0_sv2v_reg;

  always @(posedge clk_i) begin
    if(en_i) begin
      data_o_15_sv2v_reg <= data_i[15];
      data_o_14_sv2v_reg <= data_i[14];
      data_o_13_sv2v_reg <= data_i[13];
      data_o_12_sv2v_reg <= data_i[12];
      data_o_11_sv2v_reg <= data_i[11];
      data_o_10_sv2v_reg <= data_i[10];
      data_o_9_sv2v_reg <= data_i[9];
      data_o_8_sv2v_reg <= data_i[8];
      data_o_7_sv2v_reg <= data_i[7];
      data_o_6_sv2v_reg <= data_i[6];
      data_o_5_sv2v_reg <= data_i[5];
      data_o_4_sv2v_reg <= data_i[4];
      data_o_3_sv2v_reg <= data_i[3];
      data_o_2_sv2v_reg <= data_i[2];
      data_o_1_sv2v_reg <= data_i[1];
      data_o_0_sv2v_reg <= data_i[0];
    end 
  end


endmodule
module bsg_one_fifo
(
  clk_i,
  reset_i,
  ready_o,
  data_i,
  v_i,
  v_o,
  data_o,
  yumi_i
);

  input [15:0] data_i;
  output [15:0] data_o;
  input clk_i;
  input reset_i;
  input v_i;
  input yumi_i;
  output ready_o;
  output v_o;
  wire [15:0] data_o;
  wire ready_o,v_o,N0,N1,_0_net_,N2,N3,_1_net_;

  bsg_dff_reset_width_p1
  dff_full
  (
    .clk_i(clk_i),
    .reset_i(reset_i),
    .data_i(_0_net_),
    .data_o(v_o)
  );


  bsg_dff_en_width_p16_harden_p0
  dff
  (
    .clk_i(clk_i),
    .data_i(data_i),
    .en_i(_1_net_),
    .data_o(data_o)
  );

  assign _0_net_ = (N0)? N3 : 
                   (N1)? v_i : 1'b0;
  assign N0 = v_o;
  assign N1 = N2;
  assign ready_o = ~v_o;
  assign N2 = ~v_o;
  assign N3 = ~yumi_i;
  assign _1_net_ = v_i & ready_o;

endmodule
module top
(
  clk_i,
  reset_i,
  v_i,
  tag_i,
  yumi_o,
  v_o,
  ready_i
);

  input [4:0] tag_i;
  output [31:0] v_o;
  input [31:0] ready_i;
  input clk_i;
  input reset_i;
  input v_i;
  output yumi_o;

  bsg_1_to_n_tagged
  wrapper
  (
    .tag_i(tag_i),
    .v_o(v_o),
    .ready_i(ready_i),
    .clk_i(clk_i),
    .reset_i(reset_i),
    .v_i(v_i),
    .yumi_o(yumi_o)
  );


endmodule
module bsg_decode_num_out_p32
(
  i,
  o
);

  input [4:0] i;
  output [31:0] o;
  wire [31:0] o;
  assign o = { 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1 } << i;

endmodule
module bsg_decode_with_v_num_out_p32
(
  i,
  v_i,
  o
);

  input [4:0] i;
  output [31:0] o;
  input v_i;
  wire [31:0] o,lo;

  bsg_decode_num_out_p32
  bd
  (
    .i(i),
    .o(lo)
  );

  assign o[31] = v_i & lo[31];
  assign o[30] = v_i & lo[30];
  assign o[29] = v_i & lo[29];
  assign o[28] = v_i & lo[28];
  assign o[27] = v_i & lo[27];
  assign o[26] = v_i & lo[26];
  assign o[25] = v_i & lo[25];
  assign o[24] = v_i & lo[24];
  assign o[23] = v_i & lo[23];
  assign o[22] = v_i & lo[22];
  assign o[21] = v_i & lo[21];
  assign o[20] = v_i & lo[20];
  assign o[19] = v_i & lo[19];
  assign o[18] = v_i & lo[18];
  assign o[17] = v_i & lo[17];
  assign o[16] = v_i & lo[16];
  assign o[15] = v_i & lo[15];
  assign o[14] = v_i & lo[14];
  assign o[13] = v_i & lo[13];
  assign o[12] = v_i & lo[12];
  assign o[11] = v_i & lo[11];
  assign o[10] = v_i & lo[10];
  assign o[9] = v_i & lo[9];
  assign o[8] = v_i & lo[8];
  assign o[7] = v_i & lo[7];
  assign o[6] = v_i & lo[6];
  assign o[5] = v_i & lo[5];
  assign o[4] = v_i & lo[4];
  assign o[3] = v_i & lo[3];
  assign o[2] = v_i & lo[2];
  assign o[1] = v_i & lo[1];
  assign o[0] = v_i & lo[0];

endmodule
module rom_ip (
	address,
	clock,
	q);

	input	[7:0]  address;
	input	  clock;
	output	[31:0]  q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri1	  clock;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

endmodule
module uart_debug_if (/*AUTOARG*/
// Outputs
wb_dat32_o, 
// Inputs
wb_adr_i, ier, iir, fcr, mcr, lcr, msr, 
lsr, rf_count, tf_count, tstate, rstate
) ;

input [`UART_ADDR_WIDTH-1:0] 		wb_adr_i;
output [31:0] 							wb_dat32_o;
input [3:0] 							ier;
input [3:0] 							iir;
input [1:0] 							fcr;  /// bits 7 and 6 of fcr. Other bits are ignored
input [4:0] 							mcr;
input [7:0] 							lcr;
input [7:0] 							msr;
input [7:0] 							lsr;
input [`UART_FIFO_COUNTER_W-1:0] rf_count;
input [`UART_FIFO_COUNTER_W-1:0] tf_count;
input [2:0] 							tstate;
input [3:0] 							rstate;


wire [`UART_ADDR_WIDTH-1:0] 		wb_adr_i;
reg [31:0] 								wb_dat32_o;

always @(/*AUTOSENSE*/fcr or ier or iir or lcr or lsr or mcr or msr
			or rf_count or rstate or tf_count or tstate or wb_adr_i)
	case (wb_adr_i)
		                      // 8 + 8 + 4 + 4 + 8
		5'b01000: wb_dat32_o = {msr,lcr,iir,ier,lsr};
		               // 5 + 2 + 5 + 4 + 5 + 3
		5'b01100: wb_dat32_o = {8'b0, fcr,mcr, rf_count, rstate, tf_count, tstate};
		default: wb_dat32_o = 0;
	endcase // case(wb_adr_i)

endmodule // uart_debug_if
module uart_sync_flops
(
  // internal signals
  rst_i,
  clk_i,
  stage1_rst_i,
  stage1_clk_en_i,
  async_dat_i,
  sync_dat_o
);

parameter Tp            = 1;
parameter width         = 1;
parameter init_value    = 1'b0;

input                           rst_i;                  // reset input
input                           clk_i;                  // clock input
input                           stage1_rst_i;           // synchronous reset for stage 1 FF
input                           stage1_clk_en_i;        // synchronous clock enable for stage 1 FF
input   [width-1:0]             async_dat_i;            // asynchronous data input
output  [width-1:0]             sync_dat_o;             // synchronous data output


//
// Interal signal declarations
//

reg     [width-1:0]             sync_dat_o;
reg     [width-1:0]             flop_0;


// first stage
always @ (posedge clk_i or posedge rst_i)
begin
    if (rst_i)
        flop_0 <= #Tp {width{init_value}};
    else
        flop_0 <= #Tp async_dat_i;    
end

// second stage
always @ (posedge clk_i or posedge rst_i)
begin
    if (rst_i)
        sync_dat_o <= #Tp {width{init_value}};
    else if (stage1_rst_i)
        sync_dat_o <= #Tp {width{init_value}};
    else if (stage1_clk_en_i)
        sync_dat_o <= #Tp flop_0;       
end

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

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

endmodule
module uart_tfifo (clk, 
	wb_rst_i, data_in, data_out,
// Control signals
	push, // push strobe, active high
	pop,   // pop strobe, active high
// status signals
	overrun,
	count,
	fifo_reset,
	reset_status
	);


// FIFO parameters
parameter fifo_width = `UART_FIFO_WIDTH;
parameter fifo_depth = `UART_FIFO_DEPTH;
parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
parameter fifo_counter_w = `UART_FIFO_COUNTER_W;

input				clk;
input				wb_rst_i;
input				push;
input				pop;
input	[fifo_width-1:0]	data_in;
input				fifo_reset;
input       reset_status;

output	[fifo_width-1:0]	data_out;
output				overrun;
output	[fifo_counter_w-1:0]	count;

wire	[fifo_width-1:0]	data_out;

// FIFO pointers
reg	[fifo_pointer_w-1:0]	top;
reg	[fifo_pointer_w-1:0]	bottom;

reg	[fifo_counter_w-1:0]	count;
reg				overrun;
wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;

raminfr #(fifo_pointer_w,fifo_width,fifo_depth) tfifo  
        (.clk(clk), 
			.we(push), 
			.a(top), 
			.dpra(bottom), 
			.di(data_in), 
			.dpo(data_out)
		); 


always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
	if (wb_rst_i)
	begin
		top		<= #1 0;
		bottom		<= #1 1'b0;
		count		<= #1 0;
	end
	else
	if (fifo_reset) begin
		top		<= #1 0;
		bottom		<= #1 1'b0;
		count		<= #1 0;
	end
  else
	begin
		case ({push, pop})
		2'b10 : if (count<fifo_depth)  // overrun condition
			begin
				top       <= #1 top_plus_1;
				count     <= #1 count + 1'b1;
			end
		2'b01 : if(count>0)
			begin
				bottom   <= #1 bottom + 1'b1;
				count	 <= #1 count - 1'b1;
			end
		2'b11 : begin
				bottom   <= #1 bottom + 1'b1;
				top       <= #1 top_plus_1;
		        end
    default: ;
		endcase
	end
end   // always

always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
  if (wb_rst_i)
    overrun   <= #1 1'b0;
  else
  if(fifo_reset | reset_status) 
    overrun   <= #1 1'b0;
  else
  if(push & (count==fifo_depth))
    overrun   <= #1 1'b1;
end   // always

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

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

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

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


endmodule
module inst_rom_(
    wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_o, wb_dat_i, wb_sel_i, wb_we_i,
    wb_stb_i, wb_cyc_i, wb_ack_o
);

    //
    // Default address and data bus width
    //
    parameter aw = 32;   // number of address-bits
    parameter dw = 32;   // number of data-bits
    parameter ws = 4'h3; // number of wait-states

    input  wire 	wb_clk_i;
    input  wire   wb_rst_i;
    input  wire   [aw-1:0] wb_adr_i;
    output reg 	[dw-1:0] wb_dat_o;
    input  wire   [dw-1:0] wb_dat_i;
    input  wire   [3:0] wb_sel_i;
    input  wire   wb_we_i;
    input  wire   wb_stb_i;
    input  wire   wb_cyc_i;
    output reg 	wb_ack_o;

    // Wishbone read/write accesses
    wire wb_acc = wb_cyc_i & wb_stb_i;    // WISHBONE access
    wire wb_wr  = wb_acc & wb_we_i;       // WISHBONE write access
    wire wb_rd  = wb_acc & !wb_we_i;      // WISHBONE read access
	 
	wire[`InstBus]	temp_inst;
//
//	(* ramstyle = "M9K,no_rw_check" *)reg[`InstBus]  inst_mem[0:`InstMemNum-1];
//
//	initial $readmemh ( "inst_rom.data", inst_mem );
//
//    always @(posedge wb_clk_i) begin
//        if( wb_rst_i == 1'b1 ) begin
//            wb_ack_o <= 1'b0;
//				temp_inst <= `ZeroWord;
//				wb_dat_o <= `ZeroWord;
//        end else begin
//				temp_inst <= inst_mem[wb_adr_i[`InstMemNumLog2+1:2]];
//				if(wb_acc == 1'b0) begin
//					wb_ack_o <= 1'b0;
//	//            wb_dat_o <= `ZeroWord;
//	//				temp_inst <= `ZeroWord;
//			  end else if(wb_acc == 1'b1) begin
//					wb_dat_o <= {temp_inst[7:0], temp_inst[15:8], temp_inst[23:16], temp_inst[31:24]};
//					 wb_ack_o <= 1'b1;
//			  end
//			end
//      end


		
    always @(posedge wb_clk_i) begin
        if( wb_rst_i == 1'b1 ) begin
            wb_ack_o <= 1'b0;
//				temp_inst <= `ZeroWord;
				wb_dat_o <= `ZeroWord;
        end else begin
//				temp_inst <= inst_mem[wb_adr_i[`InstMemNumLog2+1:2]];
				if(wb_acc == 1'b0) begin
					wb_ack_o <= 1'b0;
	//            wb_dat_o <= `ZeroWord;
	//				temp_inst <= `ZeroWord;
			  end else if(wb_acc == 1'b1) begin
					wb_dat_o <= {temp_inst[7:0], temp_inst[15:8], temp_inst[23:16], temp_inst[31:24]};
					 wb_ack_o <= 1'b1;
			  end
			end
      end

	rom_ip rom_ip_0(
		.address(((wb_adr_i[5:0]) >> 2)),
		.clock(wb_clk_i),
		.q(temp_inst)
	);

endmodule
module clint(
	input  wire 	wb_clk_i,
	input  wire   	wb_rst_i,
	input  wire   	[31:0] wb_adr_i,
	output reg 		[31:0] wb_dat_o,
	input  wire   	[31:0] wb_dat_i,
	input  wire   	[3:0] wb_sel_i,
	input  wire   	wb_we_i,
	input  wire   	wb_stb_i,
	input  wire   	wb_cyc_i,
	output reg 		wb_ack_o,

	output reg Interrupt,
	output reg [30:0] Exception_code,
	
	// from mem
	input wire[`RegBus]	csr_mie,
	input wire[`RegBus]	csr_mstatus
);

    parameter aw = 32;   // number of address-bits
    parameter dw = 32;   // number of data-bits

    // Wishbone read/write accesses
    wire wb_acc = wb_cyc_i & wb_stb_i;    // WISHBONE access
    wire wb_wr  = wb_acc & wb_we_i;       // WISHBONE write access
    wire wb_rd  = wb_acc & !wb_we_i;      // WISHBONE read access

	reg[`DoubleRegBus]				mtime;		//机器模式计时器寄存器
	reg[`DoubleRegBus]				mtimecmp;	//机器模式计时器比较寄存器
	reg[`RegBus]						msip;
	reg software_interrupt_already;
	
    always @(posedge wb_clk_i) begin
        if( wb_rst_i == 1'b1 ) begin
            wb_ack_o <= 1'b0;
				wb_dat_o <= `ZeroWord;
				mtime <= 64'h0000000000000000;
				msip <= `ZeroWord;
				mtimecmp[63:32] <= `ZeroWord;					// 上电复位时，系统不负责设置 mtimecmp 的初值
        end else if(wb_acc == 1'b0) begin
				mtime <= mtime + 1'h1;
            wb_ack_o <= 1'b0;
//            wb_dat_o <= `ZeroWord;
        end else if(wb_acc == 1'b1) begin
				mtime <= mtime + 1'h1;
				if(wb_wr == 1'b1) begin
					if(wb_adr_i == `CLINT_BASE + 32'h4000) begin
						mtimecmp[31:0] <= wb_dat_i;
					end else if(wb_adr_i == `CLINT_BASE) begin
						msip <= wb_dat_i;
					end
				end else if(wb_rd == 1'b1) begin
					if(wb_adr_i == `CLINT_BASE + 32'h4000) begin
						wb_dat_o <= mtimecmp[31:0];
					end else if(wb_adr_i == `CLINT_BASE + 32'hbff8) begin
						wb_dat_o <= mtime[31:0];
					end else if(wb_adr_i == `CLINT_BASE) begin
						wb_dat_o <= msip;
					end
				end
				 wb_ack_o <= 1'b1;
        end
		  if(software_interrupt_already == 1'b1) begin
				msip <= 1'b0;
			end
      end
	
	always @ (*) begin
		if(wb_rst_i == 1'b1) begin
			Interrupt = 1'b0;
			Exception_code = {3'b0, 28'h0000000};
			software_interrupt_already = 1'b0;
		end else begin
			if((mtime >= mtimecmp) &&
					(csr_mstatus[3] == 1'b1) &&			// global interrupts - mstatus.MIE
								(csr_mie[7] == 1'b1))begin				// timer interrupts - mie.MTIE
				Interrupt = 1'b1;
				Exception_code = {3'b0, 28'h0000007};
			end else if((msip == 32'h00000001) &&
								(csr_mstatus[3] == 1'b1) &&			// global interrupts - mstatus.MIE
									(csr_mie[3] == 1'b1)) begin				// software interrupts - mie.MSIE
				Interrupt = 1'b1;
				Exception_code = {3'b0, 28'h0000000};
				software_interrupt_already <= 1'b1;
			end else begin
				Interrupt = 1'b0;
				Exception_code = {3'b0, 28'h0000000};
			end
		end
		if(msip == 32'h00000000) begin
			software_interrupt_already = 1'b0;
		end
	end
	
	
endmodule
module rom_ip (
	address,
	clock,
	q);

	input	[7:0]  address;
	input	  clock;
	output	[31:0]  q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri1	  clock;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

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

	altsyncram	altsyncram_component (
				.address_a (address),
				.clock0 (clock),
				.q_a (sub_wire0),
				.aclr0 (1'b0),
				.aclr1 (1'b0),
				.address_b (1'b1),
				.addressstall_a (1'b0),
				.addressstall_b (1'b0),
				.byteena_a (1'b1),
				.byteena_b (1'b1),
				.clock1 (1'b1),
				.clocken0 (1'b1),
				.clocken1 (1'b1),
				.clocken2 (1'b1),
				.clocken3 (1'b1),
				.data_a ({32{1'b1}}),
				.data_b (1'b1),
				.eccstatus (),
				.q_b (),
				.rden_a (1'b1),
				.rden_b (1'b1),
				.wren_a (1'b0),
				.wren_b (1'b0));
	defparam
		altsyncram_component.address_aclr_a = "NONE",
		altsyncram_component.clock_enable_input_a = "BYPASS",
		altsyncram_component.clock_enable_output_a = "BYPASS",
		altsyncram_component.init_file = "rom_init.mif",
		altsyncram_component.intended_device_family = "Cyclone IV E",
		altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
		altsyncram_component.lpm_type = "altsyncram",
		altsyncram_component.numwords_a = 256,
		altsyncram_component.operation_mode = "ROM",
		altsyncram_component.outdata_aclr_a = "NONE",
		altsyncram_component.outdata_reg_a = "CLOCK0",
		altsyncram_component.ram_block_type = "M9K",
		altsyncram_component.widthad_a = 8,
		altsyncram_component.width_a = 32,
		altsyncram_component.width_byteena_a = 1;


endmodule
module data_ram(
    wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_o, wb_dat_i, wb_sel_i, wb_we_i,
    wb_stb_i, wb_cyc_i, wb_ack_o
);

    //
    // Default address and data bus width
    //
    parameter aw = 32;   // number of address-bits
    parameter dw = 32;   // number of data-bits
    parameter ws = 4'h3; // number of wait-states

    input  wire 	wb_clk_i;
    input  wire   wb_rst_i;
    input  wire   [aw-1:0] wb_adr_i;
    output reg 	[dw-1:0] wb_dat_o;
    input  wire   [dw-1:0] wb_dat_i;
    input  wire   [3:0] wb_sel_i;
    input  wire   wb_we_i;
    input  wire   wb_stb_i;
    input  wire   wb_cyc_i;
    output reg 	wb_ack_o;

    // Wishbone read/write accesses
    wire wb_acc = wb_cyc_i & wb_stb_i;    // WISHBONE access
    wire wb_wr  = wb_acc & wb_we_i;       // WISHBONE write access
    wire wb_rd  = wb_acc & !wb_we_i;      // WISHBONE read access
	 
	wire[`RegBus]	temp_data;

    always @(posedge wb_clk_i) begin
        if( wb_rst_i == 1'b1 ) begin
            wb_ack_o <= 1'b0;
				wb_dat_o <= `ZeroWord;
        end else begin
				if(wb_acc == 1'b0) begin
					wb_ack_o <= 1'b0;
	//            wb_dat_o <= `ZeroWord;
			  end else if(wb_acc == 1'b1) begin
					if(wb_rd == 1'b1) begin
						wb_dat_o <= temp_data;
						wb_ack_o <= 1'b1;
					end else if(wb_wr == 1'b1) begin
						wb_ack_o <= 1'b1;
					end
			  end
			end
      end

	ram_ip ram_ip_0(
		.data(wb_dat_i),
		.rdaddress(((wb_adr_i[5:0]) >> 2)),
		.rdclock(wb_clk_i),
		.rden(wb_rd),
		.wraddress(((wb_adr_i[5:0]) >> 2)),
		.wrclock(wb_clk_i),
		.wren(wb_wr),
		.q(temp_data)
	);

endmodule
module pc_reg(

	input	wire										clk,
	input wire										rst,
	input wire[5:0]								stall,
	
	input wire										branch_flag_i,
	input wire[`RegBus]							branch_target_address_i,
	
	input wire 										flush,
	input wire[`RegBus]							new_pc,
	
	output reg[`InstAddrBus]					pc,
	output reg                    			ce,
	output wire										branch_flush
	
);

	reg[`RegBus] hold_branch_target_address;
	reg get_branch_target_address;
	reg need_branch;
	
	assign branch_flush = need_branch;

	always @ (*) begin
		if(rst == `RstEnable) begin
			hold_branch_target_address = `ZeroWord;
			need_branch = 1'b0;
		end else if(branch_flag_i == `Branch) begin
			hold_branch_target_address = branch_target_address_i;
			need_branch = 1'b1;
		end
		
		if(get_branch_target_address == 1'b1) begin
			need_branch = 1'b0;
		end
	end

	always @ (posedge clk) begin
		if (rst == `RstEnable) begin
			get_branch_target_address <= 1'b0;
			pc <= 32'h00000000;
		end else if (ce == `ChipDisable) begin
			pc <= 32'h00000000;					//SDRAM挂载在总线地址0x30000000-0x3fffffff
		end else if(flush == 1'b1) begin
			pc <= new_pc;
		end else if(stall[0] == `NoStop) begin
			if(need_branch == 1'b1) begin
				pc <= hold_branch_target_address;
				get_branch_target_address <= 1'b1;
			end else if(branch_flag_i != `Branch) begin
				pc <= pc + 4'h4;
				get_branch_target_address <= 1'b0;
		end
	end
end
	
	always @ (posedge clk) begin
		if (rst == `RstEnable) begin
			ce <= `ChipDisable;
		end else begin
			ce <= `ChipEnable;
		end
	end

endmodule
module raminfr   
        (clk, we, a, dpra, di, dpo); 

parameter addr_width = 4;
parameter data_width = 8;
parameter depth = 16;

input clk;   
input we;   
input  [addr_width-1:0] a;   
input  [addr_width-1:0] dpra;   
input  [data_width-1:0] di;   
//output [data_width-1:0] spo;   
output [data_width-1:0] dpo;   
reg    [data_width-1:0] ram [depth-1:0]; 

wire [data_width-1:0] dpo;
wire  [data_width-1:0] di;   
wire  [addr_width-1:0] a;   
wire  [addr_width-1:0] dpra;   
 
  always @(posedge clk) begin   
    if (we)   
      ram[a] <= di;   
  end   
//  assign spo = ram[a];   
  assign dpo = ram[dpra];   
endmodule
module ctrl(

	input wire										rst,
	
	input wire							stallreq_from_if,
	input wire							stallreq_from_mem,

	input wire                   stallreq_from_id,

  //来自执行阶段的暂停请求
	input wire                   stallreq_from_ex,
	
	input wire[31:0]					excepttype_i,
	input wire[`RegBus]				csr_mepc_i,
	input wire[`RegBus]				csr_mtvec_i,
	
	output reg[5:0]              stall,
	
	output reg[`RegBus]				new_pc,
	output reg							flush
	
);


	always @ (*) begin
		if(rst == `RstEnable) begin
			stall = 6'b000000;
			flush = 1'b0;
			new_pc = `ZeroWord;
		end else if(excepttype_i != `ZeroWord) begin
			flush = 1'b1;
			stall = 6'b000000;
			
			if(excepttype_i == 32'h0000000a) begin						//Mret
				new_pc = csr_mepc_i;
			end else begin
				new_pc = csr_mtvec_i;
			end
		end else if(stallreq_from_mem == `Stop) begin
			stall = 6'b011111;
			flush = 1'b0;
		end else if(stallreq_from_ex == `Stop) begin
			stall = 6'b001111;
			flush = 1'b0;
		end else if(stallreq_from_id == `Stop) begin
			stall = 6'b000111;		
			flush = 1'b0;
		end else if(stallreq_from_if == `Stop) begin
			stall = 6'b000011;										//忽略延迟槽
			flush = 1'b0;
		end else begin
			stall = 6'b000000;
			flush = 1'b0;
			new_pc = `ZeroWord;
		end    //if
	end      //always
			

endmodule
module ex_mem(

	input	wire										clk,
	input wire										rst,
	input wire[5:0]								stall,
	input wire                   				flush,
	
	
	//来自执行阶段的信息	
	input wire[`RegAddrBus]       			ex_wd,
	input wire                    			ex_wreg,
	input wire[`RegBus]					 		ex_wdata,

	input wire[`AluOpBus]						ex_aluop,
	input wire[`RegBus]							ex_mem_addr,
	input wire[`RegBus]							ex_reg2,
	
	input wire										ex_csr_reg_we,
	input wire[11:0]								ex_csr_reg_write_addr,
	input wire[`RegBus]							ex_csr_reg_data,
	
	input wire[31:0]             				ex_excepttype,
	input wire[`RegBus]          				ex_current_inst_address,
	
	//送到访存阶段的信息
	output reg[`RegAddrBus]      				mem_wd,
	output reg                   				mem_wreg,
	output reg[`RegBus]					 		mem_wdata,
	
	output reg[`AluOpBus]						mem_aluop,
	output reg[`RegBus]							mem_mem_addr,
	output reg[`RegBus]							mem_reg2,
	
	output reg										mem_csr_reg_we,
	output reg[11:0]								mem_csr_reg_write_addr,
	output reg[`RegBus]							mem_csr_reg_data,
	
	output reg[31:0]            				mem_excepttype,
	output reg[`RegBus]         				mem_current_inst_address
);


	always @ (posedge clk) begin
		if(rst == `RstEnable) begin
			mem_wd <= `NOPRegAddr;
			mem_wreg <= `WriteDisable;
			mem_wdata <= `ZeroWord;
			mem_aluop <= `EXE_NOP_OP;
			mem_mem_addr <= `ZeroWord;
			mem_reg2 <= `ZeroWord;
			
			mem_csr_reg_we <= `WriteDisable;
			mem_csr_reg_write_addr <= 12'b000000000000;
			mem_csr_reg_data <= `ZeroWord;
			
			mem_excepttype <= `ZeroWord;
			mem_current_inst_address <= `ZeroWord;
		end else if(flush == 1'b1 ) begin
			mem_wd <= `NOPRegAddr;
			mem_wreg <= `WriteDisable;
			mem_wdata <= `ZeroWord;
			mem_aluop <= `EXE_NOP_OP;
			mem_mem_addr <= `ZeroWord;
			mem_reg2 <= `ZeroWord;
			mem_csr_reg_we <= `WriteDisable;
			mem_csr_reg_write_addr <= 12'b000000000000;
			mem_csr_reg_data <= `ZeroWord;
			mem_excepttype <= `ZeroWord;
			mem_current_inst_address <= `ZeroWord;
		end else if(stall[3] == `Stop && stall[4] == `NoStop) begin
			mem_wd <= `NOPRegAddr;
			mem_wreg <= `WriteDisable;
			mem_wdata <= `ZeroWord;
			mem_aluop <= `EXE_NOP_OP;
			mem_mem_addr <= `ZeroWord;
			mem_reg2 <= `ZeroWord;
			
			mem_csr_reg_we <= `WriteDisable;
			mem_csr_reg_write_addr <= 12'b000000000000;
			mem_csr_reg_data <= `ZeroWord;
			
			mem_excepttype <= `ZeroWord;
			mem_current_inst_address <= `ZeroWord;	
		end else if(stall[3] == `NoStop) begin
			mem_wd <= ex_wd;
			mem_wreg <= ex_wreg;
			mem_wdata <= ex_wdata;
			mem_aluop <= ex_aluop;
			mem_mem_addr <= ex_mem_addr;
			mem_reg2 <= ex_reg2;
			
			mem_csr_reg_we <= ex_csr_reg_we;
			mem_csr_reg_write_addr <= ex_csr_reg_write_addr;
			mem_csr_reg_data <= ex_csr_reg_data;
			
			mem_excepttype <= ex_excepttype;
			mem_current_inst_address <= ex_current_inst_address;
		end    //if
	end      //always
			

endmodule
module div(

	input	wire										clk,
	input wire										rst,
	
	input wire                    signed_div_i,
	input wire[31:0]              opdata1_i,
	input wire[31:0]		   				opdata2_i,
	input wire                    start_i,
	input wire                    annul_i,
	
	output reg[63:0]             result_o,
	output reg			             ready_o
);

	wire[32:0] div_temp;
	reg[5:0] cnt;
	reg[64:0] dividend;
	reg[1:0] state;
	reg[31:0] divisor;	 
	reg[31:0] temp_op1;
	reg[31:0] temp_op2;
	
	assign div_temp = {1'b0,dividend[63:32]} - {1'b0,divisor};

	always @ (posedge clk) begin
		if (rst == `RstEnable) begin
			state <= `DivFree;
			ready_o <= `DivResultNotReady;
			result_o <= {`ZeroWord,`ZeroWord};
		end else begin
		  case (state)
		  	`DivFree:			begin               //DivFree状态
		  		if(start_i == `DivStart && annul_i == 1'b0) begin
		  			if(opdata2_i == `ZeroWord) begin
		  				state <= `DivByZero;
		  			end else begin
		  				state <= `DivOn;
		  				cnt <= 6'b000000;
		  				if(signed_div_i == 1'b1 && opdata1_i[31] == 1'b1 ) begin
		  					temp_op1 = ~opdata1_i + 1;
		  				end else begin
		  					temp_op1 = opdata1_i;
		  				end
		  				if(signed_div_i == 1'b1 && opdata2_i[31] == 1'b1 ) begin
		  					temp_op2 = ~opdata2_i + 1;
		  				end else begin
		  					temp_op2 = opdata2_i;
		  				end
		  				dividend <= {`ZeroWord,`ZeroWord};
              dividend[32:1] <= temp_op1;
              divisor <= temp_op2;
             end
          end else begin
						ready_o <= `DivResultNotReady;
						result_o <= {`ZeroWord,`ZeroWord};
				  end          	
		  	end
		  	`DivByZero:		begin               //DivByZero状态
         	dividend <= {`ZeroWord,`ZeroWord};
          state <= `DivEnd;		 		
		  	end
		  	`DivOn:				begin               //DivOn状态
		  		if(annul_i == 1'b0) begin
		  			if(cnt != 6'b100000) begin
               if(div_temp[32] == 1'b1) begin
                  dividend <= {dividend[63:0] , 1'b0};
               end else begin
                  dividend <= {div_temp[31:0] , dividend[31:0] , 1'b1};
               end
               cnt <= cnt + 1'b1;
             end else begin
               if((signed_div_i == 1'b1) && ((opdata1_i[31] ^ opdata2_i[31]) == 1'b1)) begin
                  dividend[31:0] <= (~dividend[31:0] + 1);
               end
               if((signed_div_i == 1'b1) && ((opdata1_i[31] ^ dividend[64]) == 1'b1)) begin              
                  dividend[64:33] <= (~dividend[64:33] + 1);
               end
               state <= `DivEnd;
               cnt <= 6'b000000;            	
             end
		  		end else begin
		  			state <= `DivFree;
		  		end	
		  	end
		  	`DivEnd:			begin               //DivEnd状态
        	result_o <= {dividend[64:33], dividend[31:0]};  
          ready_o <= `DivResultReady;
          if(start_i == `DivStop) begin
          	state <= `DivFree;
						ready_o <= `DivResultNotReady;
						result_o <= {`ZeroWord,`ZeroWord};       	
          end		  	
		  	end
		  endcase
		end
	end

endmodule
module mem_wb(

	input	wire										clk,
	input wire										rst,
	input wire[5:0]								stall,
	input wire  			                  flush,	
	

	//来自访存阶段的信息	
	input wire[`RegAddrBus]       mem_wd,
	input wire                    mem_wreg,
	input wire[`RegBus]				mem_wdata,
	
	input wire							mem_csr_reg_we,
	input wire[11:0]					mem_csr_reg_write_addr,
	input wire[`RegBus]				mem_csr_reg_data,

	//送到回写阶段的信息
	output reg[`RegAddrBus]      wb_wd,
	output reg                   wb_wreg,
	output reg[`RegBus]			  wb_wdata,

	output reg							wb_csr_reg_we,
	output reg[11:0]					wb_csr_reg_write_addr,
	output reg[`RegBus]				wb_csr_reg_data
	
);


	always @ (posedge clk) begin
		if(rst == `RstEnable) begin
			wb_wd <= `NOPRegAddr;
			wb_wreg <= `WriteDisable;
			wb_wdata <= `ZeroWord;
			
			wb_csr_reg_we <= `WriteDisable;
			wb_csr_reg_write_addr <= 12'b000000000000;
			wb_csr_reg_data <= `ZeroWord;
		end else if(flush == 1'b1 ) begin
			wb_wd <= `NOPRegAddr;
			wb_wreg <= `WriteDisable;
		   wb_wdata <= `ZeroWord;
			wb_csr_reg_we <= `WriteDisable;
			wb_csr_reg_write_addr <= 12'b000000000000;
			wb_csr_reg_data <= `ZeroWord;	
		end else if(stall[4] == `Stop && stall[5] == `NoStop) begin
			wb_wd <= `NOPRegAddr;
			wb_wreg <= `WriteDisable;
			wb_wdata <= `ZeroWord;
			
			wb_csr_reg_we <= `WriteDisable;
			wb_csr_reg_write_addr <= 12'b000000000000;
			wb_csr_reg_data <= `ZeroWord;
		end else if(stall[4] == `NoStop) begin
			wb_wd <= mem_wd;
			wb_wreg <= mem_wreg;
			wb_wdata <= mem_wdata;
			
			wb_csr_reg_we <= mem_csr_reg_we;
			wb_csr_reg_write_addr <= mem_csr_reg_write_addr;
			wb_csr_reg_data <= mem_csr_reg_data;
		end    //if
	end      //always
			

endmodule
module id_ex(

	input	wire										clk,
	input wire										rst,
	input wire[5:0]								stall,
	input wire[`RegBus]							id_link_address,

	
	//从译码阶段传递的信息
	input wire[`AluOpBus]         id_aluop,
	input wire[`AluSelBus]        id_alusel,
	input wire[`RegBus]           id_reg1,
	input wire[`RegBus]           id_reg2,
	input wire[`RegAddrBus]       id_wd,
	input wire                    id_wreg,
	
	input wire[`RegBus]				id_inst, // 来自ID模块的信号
	
	input wire							flush,
	
	input wire[`RegBus]				id_current_inst_address,
	input wire[31:0]					id_excepttype,
	
	//传递到执行阶段的信息
	output reg[`AluOpBus]         ex_aluop,
	output reg[`AluSelBus]        ex_alusel,
	output reg[`RegBus]           ex_reg1,
	output reg[`RegBus]           ex_reg2,
	output reg[`RegAddrBus]       ex_wd,
	output reg                    ex_wreg,
	output reg[`RegBus]				ex_link_address,
	
	output reg[`RegBus]				ex_inst,
	
	output reg[`RegBus]				ex_current_inst_address,
	output reg[31:0]					ex_excepttype
	
);

	always @ (posedge clk) begin
		if (rst == `RstEnable) begin
			ex_aluop <= `EXE_NOP_OP;
			ex_alusel <= `EXE_RES_NOP;
			ex_reg1 <= `ZeroWord;
			ex_reg2 <= `ZeroWord;
			ex_wd <= `NOPRegAddr;
			ex_wreg <= `WriteDisable;
			ex_link_address <= `ZeroWord;
			ex_inst <= `ZeroWord;
			 ex_excepttype <= `ZeroWord;
			 ex_current_inst_address <= `ZeroWord;
		end else if(flush == 1'b1 ) begin
			ex_aluop <= `EXE_NOP_OP;
			ex_alusel <= `EXE_RES_NOP;
			ex_reg1 <= `ZeroWord;
			ex_reg2 <= `ZeroWord;
			ex_wd <= `NOPRegAddr;
			ex_wreg <= `WriteDisable;
			ex_excepttype <= `ZeroWord;
			ex_link_address <= `ZeroWord;
			ex_inst <= `ZeroWord;
			ex_current_inst_address <= `ZeroWord;	
		end else if(stall[2] == `Stop && stall[3] == `NoStop) begin
			ex_aluop <= `EXE_NOP_OP;
			ex_alusel <= `EXE_RES_NOP;
			ex_reg1 <= `ZeroWord;
			ex_reg2 <= `ZeroWord;
			ex_wd <= `NOPRegAddr;
			ex_wreg <= `WriteDisable;
			ex_link_address <= `ZeroWord;
			ex_inst <= `ZeroWord;
			ex_excepttype <= `ZeroWord;
			ex_current_inst_address <= `ZeroWord;
		end else if(stall[2] == `NoStop) begin		
			ex_aluop <= id_aluop;
			ex_alusel <= id_alusel;
			ex_reg1 <= id_reg1;
			ex_reg2 <= id_reg2;
			ex_wd <= id_wd;
			ex_wreg <= id_wreg;
			ex_link_address <= id_link_address;
			ex_inst <= id_inst;
	      ex_excepttype <= id_excepttype;
	      ex_current_inst_address <= id_current_inst_address;	
		end
	end
	
endmodule
module regfile(

	input	wire										clk,
	input wire										rst,
	
	//写端口
	input wire										we,
	input wire[`RegAddrBus]				waddr,
	input wire[`RegBus]						wdata,
	
	//读端口1
	input wire										re1,
	input wire[`RegAddrBus]			  raddr1,
	output reg[`RegBus]           rdata1,
	
	//读端口2
	input wire										re2,
	input wire[`RegAddrBus]			  raddr2,
	output reg[`RegBus]           rdata2
	
);

	reg[`RegBus]  regs[0:`RegNum-1];
	
	initial regs[0] = `ZeroWord; 

	always @ (posedge clk) begin
		if (rst == `RstDisable) begin
			if((we == `WriteEnable) && (waddr != `RegNumLog2'h0)) begin
				regs[waddr] = wdata;
			end
		end
	end
	
	always @ (*) begin
		if(rst == `RstEnable) begin
			  rdata1 = `ZeroWord;
	  end else if(raddr1 == `RegNumLog2'h0) begin
	  		rdata1 = `ZeroWord;
	  end else if((raddr1 == waddr) && (we == `WriteEnable) 
	  	            && (re1 == `ReadEnable)) begin
	  	  rdata1 = wdata;
	  end else if(re1 == `ReadEnable) begin
	      rdata1 = regs[raddr1];
	  end else begin
	      rdata1 = `ZeroWord;
	  end
	end

	always @ (*) begin
		if(rst == `RstEnable) begin
			  rdata2 = `ZeroWord;
	  end else if(raddr2 == `RegNumLog2'h0) begin
	  		rdata2 = `ZeroWord;
	  end else if((raddr2 == waddr) && (we == `WriteEnable) 
	  	            && (re2 == `ReadEnable)) begin
	  	  rdata2 = wdata;
	  end else if(re2 == `ReadEnable) begin
	      rdata2 = regs[raddr2];
	  end else begin
	      rdata2 = `ZeroWord;
	  end
	end

endmodule
module if_id(

	input	wire										clk,
	input wire										rst,
	input wire[5:0]								stall,
	
	input wire										flush,
	input wire										branch_flush,
	

	input wire[`InstAddrBus]					if_pc,
	input wire[`InstBus]          			if_inst,
	output reg[`InstAddrBus]      			id_pc,
	output reg[`InstBus]          			id_inst  
	
);

	always @ (posedge clk) begin
		if (rst == `RstEnable) begin
			id_pc <= `ZeroWord;
			id_inst <= `ZeroWord;
		end else if((flush == 1'b1) || (branch_flush == 1'b1)) begin
			id_pc <= `ZeroWord;
			id_inst <= `ZeroWord;
		end else if(stall[1] == `Stop && stall[2] == `NoStop) begin
			id_pc <= `ZeroWord;
			id_inst <= `ZeroWord;
		end else if(stall[1] == `NoStop) begin
			id_pc <= if_pc;
			id_inst <= if_inst;
		end
	end

endmodule
module snes_dejitter(
    input MCLK_XTAL_i, //NTSC master clock source: 21.477272MHz from oscillator circuit
    input MCLK_EXT_i,  //PAL master clock source: 21.28137MHz (3-CHIP) or 17.73MHz (1-CHIP) from external source
    input MCLK_SEL_i,  //Output clock/csync mode: De-jitter/NTSC (0), Bypass/PAL (1)
    input CSYNC_i,
    output MCLK_XTAL_o,
    output GCLK_o,
    output CSYNC_o,
    output reg SC_o
);

wire mclk_ntsc = MCLK_XTAL_i;
wire mclk_ntsc_dejitter = mclk_ntsc & gclk_en;
wire mclk_pal = MCLK_EXT_i;

assign GCLK_o = MCLK_SEL_i ? mclk_pal : mclk_ntsc_dejitter;
assign CSYNC_o = MCLK_SEL_i ? CSYNC_i : csync_dejitter;

assign MCLK_XTAL_o = ~MCLK_XTAL_i;

reg [10:0] h_cnt;
reg [2:0] g_cyc;
reg csync_prev;
reg csync_dejitter;
reg gclk_en;
reg [1:0] sc_ctr;


always @(posedge mclk_ntsc) begin
    if ((h_cnt >= 1024) && (csync_prev==1'b1) && (CSYNC_i==1'b0)) begin
        h_cnt <= 0;
        if (h_cnt == 340*4-1)
            g_cyc <= 4;
        else
            csync_dejitter <= CSYNC_i;
    end else begin
        h_cnt <= h_cnt + 1'b1;
        if (g_cyc > 0)
            g_cyc <= g_cyc - 1'b1;
        if (g_cyc <= 1)
            csync_dejitter <= CSYNC_i;
    end

    csync_prev <= CSYNC_i;
end

always @(posedge mclk_ntsc) begin
    if (sc_ctr == 2'h2) begin
        sc_ctr <= 2'h0;
        SC_o <= ~SC_o;
    end else begin
        sc_ctr <= sc_ctr + 2'h1;
    end
end

`ifdef EDGE_SENSITIVE_CLKEN
//Update clock gate enable signal on negative edge
always @(negedge mclk_ntsc) begin
    gclk_en <= (g_cyc == 0);
end
`else
//ATF1502AS macrocells support D latch mode,
//enabling level sensitive update of gclk_en during negative phase
always @(*) begin
    if (!mclk_ntsc)
        gclk_en <= (g_cyc == 0);
end
`endif

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

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

endmodule
module pll_for_disp (
	areset,
	inclk0,
	c0,
	c1,
	c2);

	input	  areset;
	input	  inclk0;
	output	  c0;
	output	  c1;
	output	  c2;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri0	  areset;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

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

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

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

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


endmodule
module pll (
	areset,
	inclk0,
	c0,
	c1,
	c2,
	c3,
	locked);

	input	  areset;
	input	  inclk0;
	output	  c0;
	output	  c1;
	output	  c2;
	output	  c3;
	output	  locked;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri0	  areset;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

endmodule
module addressRAM(
	input [4:0] step,
	output reg re_RAM,
	output reg [12:0] firstaddr, lastaddr
);
parameter picture_size = 0;
parameter convolution_size = 0;

parameter picture_storage_limit = picture_size*picture_size;
parameter convweight = picture_storage_limit + (1*4 + 4*4 + 4*8 + 8*8) * convolution_size;  // all convolution weights [784:1828]

parameter conv1 = picture_storage_limit + 1*4 * convolution_size;
parameter conv2 = picture_storage_limit + (1*4 + 4*4) * convolution_size;
parameter conv3 = picture_storage_limit + (1*4 + 4*4 + 4*8) * convolution_size;
parameter conv4 = picture_storage_limit + (1*4 + 4*4 + 4*8 + 8*8) * convolution_size;
parameter conv5 = picture_storage_limit + (1*4 + 4*4 + 4*8 + 8*8 + 8*16) * convolution_size;
parameter conv6 = picture_storage_limit + (1*4 + 4*4 + 4*8 + 8*8 + 8*16 + 16*16) * convolution_size;

parameter dense = conv6+176;

always @(step)
case (step)
1'd1: begin       //picture
		firstaddr = 0;
		lastaddr = picture_storage_limit;
		re_RAM = 1;
	  end 
2'd2: begin       //weights conv1 
		firstaddr = picture_storage_limit;
		lastaddr = conv1;
		re_RAM = 1;
	  end
3'd4: begin			//weights conv2
		firstaddr = conv1;
      lastaddr = conv2;
		re_RAM = 1;
      end		
3'd6: begin			//weights conv3
		firstaddr = conv2;
		lastaddr = conv3;
		re_RAM = 1;
	  end
4'd8: begin			//weights conv4
		firstaddr = conv3;
		lastaddr = conv4;
		re_RAM = 1;
		end
4'd10: begin		//weights conv5
		firstaddr = conv4;
		lastaddr = conv5;
		re_RAM = 1;
	  end
4'd12: begin		//weights conv6
		firstaddr = conv5;
		lastaddr = conv6;
		re_RAM = 1;
	  end
4'd14: begin		//weights conv7
		firstaddr = conv6;
		lastaddr =  dense;
		re_RAM = 1;
	  end
default:
			begin
				re_RAM = 0;
			end
endcase
endmodule
module border(
    input clk, go,
    input [9:0] i,
    input [4:0] matrix,
    output reg [1:0] prov
);
reg [10:0] j;
always @(posedge clk)
begin
    if (go == 1)
    begin
        prov = 0;
        for (j = 1'b1; j <= matrix; j = j + 1'b1)
        begin
            if ((i == j*matrix-1'b1) && (prov != 2'b10))
                prov = 2'b10;
            if (((i == 0) || (i == j*matrix)) && (prov != 2'b11))
                prov = 2'b11;
        end
    end
    else
        prov = 0;
end
endmodule
module RAM(qp,qtp,qw,dp,dtp,dw,write_addressp,read_addressp,write_addresstp,read_addresstp,write_addressw,read_addressw,we_p,we_tp,we_w,re_p,re_tp,re_w,clk);
parameter picture_size=0;
parameter SIZE_1=0;
parameter SIZE_2=0;
parameter SIZE_4=0;
parameter SIZE_9=0;
parameter SIZE_address_pix=0;
parameter SIZE_address_pix_t=0;
parameter SIZE_address_wei=0;

output reg signed [SIZE_1-1:0] qp;       //read data
output reg signed [(SIZE_2)*1-1:0] qtp;       //read data
output reg signed [SIZE_9-1:0] qw;      //read weight
input signed [SIZE_1-1:0] dp;   //write data
input signed [(SIZE_2)*1-1:0] dtp;   //write data
input signed [SIZE_9-1:0] dw;   //write weight
input [SIZE_address_pix-1:0] write_addressp, read_addressp;
input [SIZE_address_pix_t-1:0] write_addresstp, read_addresstp;
input [SIZE_address_wei-1:0] write_addressw, read_addressw;
input we_p,we_tp,we_w,re_p,re_tp,re_w,clk;

reg signed [SIZE_1-1:0] mem [0:picture_size*picture_size*8+picture_size*picture_size-1];
reg signed [(SIZE_2)*1-1:0] mem_t [0:picture_size*picture_size*4-1];
reg signed [SIZE_9-1:0] weight [0:256];
always @ (posedge clk)
    begin
        if (we_p) mem[write_addressp] <= dp;
		if (we_tp) mem_t[write_addresstp] <= dtp;
		if (we_w) weight[write_addressw] <= dw;
    end
always @ (posedge clk)
    begin
        if (re_p) qp <= mem[read_addressp];
		if (re_tp) qtp <= mem_t[read_addresstp];
        if (re_w) qw <= weight[read_addressw];
    end
endmodule
module conv(clk, Y1, prov, matrix, matrix2, i, w1, w2, w3, w4, w5, w6, w7, w8, w9,w11, w12, w13, w14, w15, w16, w17, w18, w19, conv_en, dense_en);
parameter SIZE=23;
input clk;
output reg signed [SIZE+SIZE-2:0] Y1;
input [1:0] prov;
input [4:0] matrix;
input [9:0] matrix2;
input [9:0] i;
input signed [SIZE-1:0] w1, w2, w3, w4, w5, w6, w7, w8, w9;
input signed [SIZE-1:0] w11, w12, w13, w14, w15, w16, w17, w18, w19;
input conv_en;
input dense_en;

always @(posedge clk)
    begin
		if (conv_en==1)
			begin
        Y1=0;
        Y1 = Y1+Y(w1,w11);
		  //$display("center:",w1,w11);
        //right
        if ((prov!=2'b10)||(dense_en==1))
            begin
                Y1 = Y1+Y(w2,w12);
					 //$display("right:",w2,w12);
            end
        //left
        if ((prov!=2'b11)||(dense_en==1))
            begin
                Y1 = Y1+Y(w3,w13);
					 //$display("left:",w3,w13);
            end
        //downleft
        if (((i<matrix2-matrix)&&(prov!=2'b11))||(dense_en==1))
            begin
                Y1 = Y1+Y(w4,w14);
					 //$display("downleft:",w4,w14);
            end
        //upright
        if (((i>matrix-1'b1)&&(prov!=2'b10))||(dense_en==1))
            begin
                Y1 = Y1+Y(w5,w15);
					 //$display("upright:",w5,w15);
            end
        //down
        if ((i<matrix2-matrix)||(dense_en==1))
            begin
                Y1 = Y1+Y(w6,w16);
					 //$display("down:",w6,w16);
            end
        //up
        if ((i>matrix-1'b1)||(dense_en==1))
            begin
                Y1 = Y1+Y(w7,w17);
					 //$display("up:",w7,w17);
            end
        //downright
        if (((i<matrix2-matrix)&&(prov!=2'b10))||(dense_en==1))
            begin
                Y1 = Y1+Y(w8,w18);
					 //$display("downright:",w8,w18);
            end
        //upleft
        if (((i>matrix-1'b1)&&(prov!=2'b11))||(dense_en==1))
            begin
                Y1 = Y1+Y(w9,w19);
					 //$display("upleft:",w9,w19);
            end
			end
    end

function signed [SIZE+SIZE-2:0] Y;
    input signed [SIZE-1:0] a, b;
    begin
        Y = a*b;
        //Y = Y>>SIZE-1;
    end
endfunction

endmodule