dakies/OSS_Verilog huggingface dataset:
module buffer_test();

   localparam B = 1024;

   reg CLOCK_50, rst;
   reg [31:0] counter;
   reg        new_sample_val;

   wire [31:0] pitch_shift_out;
   wire        pitch_shift_val;

   // make reset
   initial begin
      CLOCK_50 = 1'b0;
      rst = 1'b0;
      counter = 32'b0;
      new_sample_val = 1'b0;
      #50
        rst = 1'b1;
      #100
        rst = 1'b0;
   end

   // make clock
   always begin
      #10
        CLOCK_50 = !CLOCK_50;
   end

   always begin
      #50
        counter = counter + 1;
      new_sample_val = 1'b1;
      #10
        new_sample_val = 1'b0;

   end

   buffer #(B) b1
     (
      //inputs
      .clk(CLOCK_50),
      .rst(rst),
      .delta(8'b01000000), // 1 in fixed3.5
      .new_sample_val(new_sample_val),
      .new_sample_data(counter),
      .out_sel(1'b0),
      .delta_mode(1'b0),
      //outputs
      .pitch_shift_out(pitch_shift_out),
      .pitch_shift_val(pitch_shift_val)
      );

endmodule
module butter_test();

   reg rst, CLOCK_50;
   reg [31:0] counter;
   reg        audio_input_ready;
   // DDS update signal for testing
   reg [31:0] dds_accum;
   // DDS LUT
   reg [31:0] sine_out;
   wire [31:0] my_out;

   // make reset
   initial begin
      counter = 32'b0;
      CLOCK_50 = 1'b0;
      audio_input_ready = 1'b0;
      dds_accum = 32'd0;
      sine_out = 32'h7fff_ffff;
      rst = 1'b0;
      #50
        rst = 1'b1;
      #100
        rst = 1'b0;
   end

   // make clock
   always begin
      #10
        CLOCK_50 = !CLOCK_50;
   end

   always begin
      #1000000
        sine_out = ~sine_out;
   end

   always begin
      #20813
        audio_input_ready = 1;
      #20
        audio_input_ready = 0;
   end

   // update phase accumulator
   // sync to audio data rate (48kHz) using audio_input_ready signal
   /*always @(posedge CLOCK_50) begin //CLOCK_50
    // Fout = (sample_rate)/(2^32)*(constant)
    // then Fout=48000/(2^32)*(44739242) = 500 Hz
    if (audio_input_ready) dds_accum <= dds_accum + 32'd44739242;
   end*/
   // DDS sine wave ROM
   //sync_rom sineTable(CLOCK_50, dds_accum[31:24], sine_out);

   //Filter: cutoff=0.145833
   IIR6_32bit_fixed filter(
                            .audio_out (my_out),
                            .audio_in (sine_out),
                            .scale (3'd3),
                            .b1 (32'h226C),
                            .b2 (32'hCE8B),
                            .b3 (32'h2045B),
                            .b4 (32'h2B07A),
                            .b5 (32'h2045B),
                            .b6 (32'hCE8B),
                            .b7 (32'h226C),
                            .a2 (32'h21DC9D38),
                            .a3 (32'hC2BABD8C),
                            .a4 (32'h3C58991F),
                            .a5 (32'hDDFDB62D),
                            .a6 (32'hA5FA11C),
                            .a7 (32'hFEAA19B2),
                            .clk(CLOCK_50),
                            .data_val(audio_input_ready),
                            .rst(rst),
                            .audio_out_val(audio_out_val)
                            ); //end filter

endmodule
module RAM_512_18
  #(parameter B = 1024)
   (
    output signed [31:0]    q,
    input signed [31:0]     data,
    input [($clog2(B)-1):0] wraddress, rdaddress,
    input                   wren, rden, clock
    );

   reg [8:0]                read_address_reg;
   reg signed [31:0]        mem [(B-1):0] /*synthesis ramstyle = M10K" */;
   reg                      rden_reg;

   always @(posedge clock) begin
      if (wren)
        mem[wraddress] <= data;
   end

   always @(posedge clock) begin
      read_address_reg <= rdaddress;
      rden_reg <= rden;
   end

   assign q = (rden_reg) ? mem[read_address_reg] : 0;

endmodule
module project_top();

   reg rst, clk;
   wire [31:0] bus_addr;        // Avalon address
   wire [3:0]  bus_byte_enable; // four bit byte read/write mask
   wire        bus_read;        // high when requesting data
   wire        bus_write;       //  high when writing data
   wire [31:0] bus_write_data;       //  data to send to Avalog bus
   reg         bus_ack;         //  Avalon bus raises this when done
   reg [31:0]  bus_read_data;   // data from Avalon bus
   reg [31:0]  counter;

   wire [31:0] audio_fifo_address  = 32'h00003044; // Avalon address +4
   wire [31:0] audio_left_address  = 32'h00003048; // Avalon address +8
   wire [31:0] audio_right_address = 32'h0000304c; // Avalon address +12

   // make reset
   initial begin
      bus_read_data = 32'b0;

      counter = 32'b0;
      clk = 1'b0;
      rst = 1'b0;
      #50
        rst = 1'b1;
      #100
        rst = 1'b0;
   end

   // make clock
   always begin
      #10
        clk = !clk;
   end

   always @(posedge clk) begin

      // fake bus acjs
      bus_ack <= bus_write | bus_read;

   end

   always @(posedge bus_read) begin

      // fake bus reads
      if (bus_addr == audio_fifo_address) begin
         bus_read_data <= (8'd3 << 24) | 8'd2; // allow reads and writes
      end
      else if ((bus_addr == audio_right_address)) begin
         counter <= counter + 1;
         bus_read_data <= counter;
      end

   end

   EBABWrapper ebab_wrapper
     (
      // Outputs
      .bus_byte_enable(bus_byte_enable),
      .bus_read(bus_read),
      .bus_write(bus_write),
      .bus_write_data(bus_write_data),
      .bus_addr(bus_addr),
      // Inputs
      .clk(clk),
      .rst(rst),
      .bus_ack(bus_ack),
      .bus_read_data(bus_read_data)
      );

endmodule
module signed_mult (out, a, b);

   output    [31:0]  out;
   input   signed [31:0] a;
   input   signed [31:0] b;

   wire  signed [31:0]   out;
   wire  signed [63:0]   mult_out;

   assign mult_out = a * b;
   //assign out = mult_out[33:17];
   assign out = {mult_out[63], mult_out[59:30]};
endmodule
module simple_ram
  #(parameter width     = 1,
    parameter widthad   = 1
    )
   (
    input 		   clk,
    
    input [widthad-1:0]    wraddress,
    input 		   wren,
    input [width-1:0] 	   data,
    
    input [widthad-1:0]    rdaddress,
    output reg [width-1:0] q
    );

reg [width-1:0] mem [(2**widthad)-1:0];

always @(posedge clk) begin
    if(wren) mem[wraddress] <= data;
    
    q <= mem[rdaddress];
end

endmodule
module testbench;
	reg clk = 1;
	reg resetn = 0;
	wire trap;

	always #5 clk = ~clk;

	initial begin
		if ($test$plusargs("vcd")) begin
			$dumpfile("testbench.vcd");
			$dumpvars(0, testbench);
		end
		repeat (100) @(posedge clk);
		resetn <= 1;
		repeat (1000) @(posedge clk);
		$finish;
	end

	wire mem_valid;
	wire mem_instr;
	reg mem_ready;
	wire [31:0] mem_addr;
	wire [31:0] mem_wdata;
	wire [3:0] mem_wstrb;
	reg  [31:0] mem_rdata;

	always @(posedge clk) begin
		if (mem_valid && mem_ready) begin
			if (mem_instr)
				$display("ifetch 0x%08x: 0x%08x", mem_addr, mem_rdata);
			else if (mem_wstrb)
				$display("write  0x%08x: 0x%08x (wstrb=%b)", mem_addr, mem_wdata, mem_wstrb);
			else
				$display("read   0x%08x: 0x%08x", mem_addr, mem_rdata);
		end
	end

	picorv32 #(
	) uut (
		.clk         (clk        ),
		.resetn      (resetn     ),
		.trap        (trap       ),
		.mem_valid   (mem_valid  ),
		.mem_instr   (mem_instr  ),
		.mem_ready   (mem_ready  ),
		.mem_addr    (mem_addr   ),
		.mem_wdata   (mem_wdata  ),
		.mem_wstrb   (mem_wstrb  ),
		.mem_rdata   (mem_rdata  )
	);

	reg [31:0] memory [0:255];

	initial begin
		memory[0] = 32'h 3fc00093; //       li      x1,1020
		memory[1] = 32'h 0000a023; //       sw      x0,0(x1)
		memory[2] = 32'h 0000a103; // loop: lw      x2,0(x1)
		memory[3] = 32'h 00110113; //       addi    x2,x2,1
		memory[4] = 32'h 0020a023; //       sw      x2,0(x1)
		memory[5] = 32'h ff5ff06f; //       j       <loop>
	end

	always @(posedge clk) begin
		mem_ready <= 0;
		if (mem_valid && !mem_ready) begin
			if (mem_addr < 1024) begin
				mem_ready <= 1;
				mem_rdata <= memory[mem_addr >> 2];
				if (mem_wstrb[0]) memory[mem_addr >> 2][ 7: 0] <= mem_wdata[ 7: 0];
				if (mem_wstrb[1]) memory[mem_addr >> 2][15: 8] <= mem_wdata[15: 8];
				if (mem_wstrb[2]) memory[mem_addr >> 2][23:16] <= mem_wdata[23:16];
				if (mem_wstrb[3]) memory[mem_addr >> 2][31:24] <= mem_wdata[31:24];
			end
			/* add memory-mapped IO here */
		end
	end
endmodule
module testbench #(
	parameter AXI_TEST = 0,
	parameter VERBOSE = 0
);
	reg clk = 1;
	reg resetn = 0;
	wire trap;

	always #5 clk = ~clk;

	initial begin
		repeat (100) @(posedge clk);
		resetn <= 1;
	end

	initial begin
		if ($test$plusargs("vcd")) begin
			$dumpfile("testbench.vcd");
			$dumpvars(0, testbench);
		end
		repeat (1000000) @(posedge clk);
		$display("TIMEOUT");
		$finish;
	end

	wire trace_valid;
	wire [35:0] trace_data;
	integer trace_file;

	initial begin
		if ($test$plusargs("trace")) begin
			trace_file = $fopen("testbench.trace", "w");
			repeat (10) @(posedge clk);
			while (!trap) begin
				@(posedge clk);
				if (trace_valid)
					$fwrite(trace_file, "%x\n", trace_data);
			end
			$fclose(trace_file);
			$display("Finished writing testbench.trace.");
		end
	end

	picorv32_wrapper #(
		.AXI_TEST (AXI_TEST),
		.VERBOSE  (VERBOSE)
	) top (
		.clk(clk),
		.resetn(resetn),
		.trap(trap),
		.trace_valid(trace_valid),
		.trace_data(trace_data)
	);
endmodule
module testbench #(
	parameter VERBOSE = 0
);
	reg clk = 1;
	reg resetn = 1;
	wire trap;

	always #5 clk = ~clk;

	initial begin
		repeat (100) @(posedge clk);
		resetn <= 0;
	end

	initial begin
		if ($test$plusargs("vcd")) begin
			$dumpfile("testbench.vcd");
			$dumpvars(0, testbench);
		end
		repeat (1000000) @(posedge clk);
		$display("TIMEOUT");
		$finish;
	end

	wire trace_valid;
	wire [35:0] trace_data;
	integer trace_file;

	initial begin
		if ($test$plusargs("trace")) begin
			trace_file = $fopen("testbench.trace", "w");
			repeat (10) @(posedge clk);
			while (!trap) begin
				@(posedge clk);
				if (trace_valid)
					$fwrite(trace_file, "%x\n", trace_data);
			end
			$fclose(trace_file);
			$display("Finished writing testbench.trace.");
		end
	end

	picorv32_wrapper #(
		.VERBOSE (VERBOSE)
	) top (
		.wb_clk(clk),
		.wb_rst(resetn),
		.trap(trap),
		.trace_valid(trace_valid),
		.trace_data(trace_data)
	);
endmodule
module picorv32_wrapper #(
	parameter VERBOSE = 0
) (
	input wb_clk,
	input wb_rst,
	output trap,
	output trace_valid,
	output [35:0] trace_data
);
	wire tests_passed;
	reg [31:0] irq = 0;
	wire mem_instr;

	reg [15:0] count_cycle = 0;
	always @(posedge wb_clk) count_cycle <= !wb_rst ? count_cycle + 1 : 0;

	always @* begin
		irq = 0;
		irq[4] = &count_cycle[12:0];
		irq[5] = &count_cycle[15:0];
	end

	wire [31:0] wb_m2s_adr;
	wire [31:0] wb_m2s_dat;
	wire [3:0] wb_m2s_sel;
	wire wb_m2s_we;
	wire wb_m2s_cyc;
	wire wb_m2s_stb;
	wire [31:0] wb_s2m_dat;
	wire wb_s2m_ack;

	wb_ram #(
		.depth (128*1024),
		.VERBOSE (VERBOSE)
	) ram ( // Wishbone interface
		.wb_clk_i(wb_clk),
		.wb_rst_i(wb_rst),

		.wb_adr_i(wb_m2s_adr),
		.wb_dat_i(wb_m2s_dat),
		.wb_stb_i(wb_m2s_stb),
		.wb_cyc_i(wb_m2s_cyc),
		.wb_dat_o(wb_s2m_dat),
		.wb_ack_o(wb_s2m_ack),
		.wb_sel_i(wb_m2s_sel),
		.wb_we_i(wb_m2s_we),

		.mem_instr(mem_instr),
		.tests_passed(tests_passed)
	);

	picorv32_wb #(
`ifndef SYNTH_TEST
`ifdef SP_TEST
		.ENABLE_REGS_DUALPORT(0),
`endif
`ifdef COMPRESSED_ISA
		.COMPRESSED_ISA(1),
`endif
		.ENABLE_MUL(1),
		.ENABLE_DIV(1),
		.ENABLE_IRQ(1),
		.ENABLE_TRACE(1)
`endif
	) uut (
		.trap (trap),
		.irq (irq),
		.trace_valid (trace_valid),
		.trace_data (trace_data),
		.mem_instr(mem_instr),

		.wb_clk_i(wb_clk),
		.wb_rst_i(wb_rst),

		.wbm_adr_o(wb_m2s_adr),
		.wbm_dat_i(wb_s2m_dat),
		.wbm_stb_o(wb_m2s_stb),
		.wbm_ack_i(wb_s2m_ack),
		.wbm_cyc_o(wb_m2s_cyc),
		.wbm_dat_o(wb_m2s_dat),
		.wbm_we_o(wb_m2s_we),
		.wbm_sel_o(wb_m2s_sel)
	);

	reg [1023:0] firmware_file;
	initial begin
		if (!$value$plusargs("firmware=%s", firmware_file))
			firmware_file = "firmware/firmware.hex";
		$readmemh(firmware_file, ram.mem);
	end

	integer cycle_counter;
	always @(posedge wb_clk) begin
		cycle_counter <= !wb_rst ? cycle_counter + 1 : 0;
		if (!wb_rst && trap) begin
`ifndef VERILATOR
			repeat (10) @(posedge wb_clk);
`endif
			$display("TRAP after %1d clock cycles", cycle_counter);
			if (tests_passed) begin
				$display("ALL TESTS PASSED.");
				$finish;
			end else begin
				$display("ERROR!");
				if ($test$plusargs("noerror"))
					$finish;
				$stop;
			end
		end
	end
endmodule
module wb_ram #(
	parameter depth = 256,
	parameter memfile = "",
	parameter VERBOSE = 0
) (
	input wb_clk_i,
	input wb_rst_i,

	input [31:0] wb_adr_i,
	input [31:0] wb_dat_i,
	input [3:0] wb_sel_i,
	input wb_we_i,
	input wb_cyc_i,
	input wb_stb_i,

	output reg wb_ack_o,
	output reg [31:0] wb_dat_o,

	input mem_instr,
	output reg tests_passed
);

	reg verbose;
	initial verbose = $test$plusargs("verbose") || VERBOSE;

	initial tests_passed = 0;

	reg [31:0] adr_r;
	wire valid = wb_cyc_i & wb_stb_i;

	always @(posedge wb_clk_i) begin
		adr_r <= wb_adr_i;
		// Ack generation
		wb_ack_o <= valid & !wb_ack_o;
		if (wb_rst_i)
		begin
			adr_r <= {32{1'b0}};
			wb_ack_o <= 1'b0;
		end
	end

	wire ram_we = wb_we_i & valid & wb_ack_o;

	wire [31:0] waddr = adr_r[31:2];
	wire [31:0] raddr = wb_adr_i[31:2];
	wire [3:0] we = {4{ram_we}} & wb_sel_i;

	wire [$clog2(depth/4)-1:0] raddr2 = raddr[$clog2(depth/4)-1:0];
	wire [$clog2(depth/4)-1:0] waddr2 = waddr[$clog2(depth/4)-1:0];

	reg [31:0] mem [0:depth/4-1] /* verilator public */;

	always @(posedge wb_clk_i) begin
		if (ram_we) begin
			if (verbose)
				$display("WR: ADDR=%08x DATA=%08x STRB=%04b",
					adr_r, wb_dat_i, we);

			if (adr_r[31:0] == 32'h1000_0000)
				if (verbose) begin
					if (32 <= wb_dat_i[7:0] && wb_dat_i[7:0] < 128)
						$display("OUT: '%c'", wb_dat_i[7:0]);
					else
						$display("OUT: %3d", wb_dat_i[7:0]);
				end else begin
					$write("%c", wb_dat_i[7:0]);
`ifndef VERILATOR
					$fflush();
`endif
				end
			else
			if (adr_r[31:0] == 32'h2000_0000)
				if (wb_dat_i[31:0] == 123456789)
					tests_passed = 1;
		end
	end

	always @(posedge wb_clk_i) begin
		if (waddr2 < 128 * 1024 / 4) begin
			if (we[0])
				mem[waddr2][7:0] <= wb_dat_i[7:0];

			if (we[1])
				mem[waddr2][15:8] <= wb_dat_i[15:8];

			if (we[2])
				mem[waddr2][23:16] <= wb_dat_i[23:16];

			if (we[3])
				mem[waddr2][31:24] <= wb_dat_i[31:24];

		end

		if (valid & wb_ack_o & !ram_we)
			if (verbose)
				$display("RD: ADDR=%08x DATA=%08x%s", adr_r, mem[raddr2], mem_instr ? " INSN" : "");

		wb_dat_o <= mem[raddr2];
	end

	initial begin
		if (memfile != "")
			$readmemh(memfile, mem);
	end
endmodule
module controller(
    input           clk,
    input           reset_n,
    input   [7:0]   input_spike,
    output  [7:0]   output_spike
);
    

    wire    [7:0]   output_spike_layer_0;


    layer_0 uut_layer_0 (
        .clk(clk), .reset_n(reset_n),
        .input_spike(input_spike),
        .output_spike(output_spike_layer_0)
    );
    layer_1 uut_layer_1 (
        .clk(clk), .reset_n(reset_n),
        .input_spike(output_spike_layer_0),
        .output_spike(output_spike)
    );

endmodule
module tb_controller;
    reg                 clk, reset_n;
    reg         [7:0]   input_spike;

    wire        [7:0]   output_spike;

    parameter           STEP = 10;

    controller uut_controller (
        .clk(clk), .reset_n(reset_n),
        .input_spike(input_spike),
        .output_spike(output_spike)
    );

    always #(STEP/2) clk = ~clk;
    
    initial
    begin
        $dumpfile("tb_controller.vcd");
        $dumpvars(0, tb_controller);
        clk = 0; reset_n = 1; input_spike = 8'b00000000;
        #1 reset_n = 0;
        #2 reset_n = 1;
        
        #STEP input_spike = 8'b11111111;
        #STEP input_spike = 8'b00000000;
        #STEP input_spike = 8'b11111111;
        #STEP input_spike = 8'b00000000;
        #STEP
        $finish;
    end

endmodule
module cond ( nzcv,  condition_code, will_this_be_executed);
input wire[3:0] nzcv;
input wire[3:0] condition_code;
output reg will_this_be_executed;

always @* begin

case(condition_code)
	0: begin	//EQ
	if(nzcv[2] == 1)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end

	1: begin //NE
	if(nzcv[2] == 0)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end
	
	2: begin //CS
	if(nzcv[1] == 1)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	3: begin //CC	
	if(nzcv[1] == 0)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	4: begin //MI
	if(nzcv[3] == 1)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	5: begin //PL
	if(nzcv[3] == 0)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	6: begin //VS
	if(nzcv[0] == 1)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	7: begin //VC
	if(nzcv[0] == 0)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	8: begin //HI
	if(nzcv[1] == 1 && nzcv[2] == 0)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	9: begin //LS
	if(nzcv[1] == 0 && nzcv[2] == 1)  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	10: begin //GE
	if(nzcv[3] == nzcv[0])  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	11: begin //LT
	if(nzcv[3] != nzcv[0])  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	12: begin //GT
	if(nzcv[2] == 0 && nzcv[3] == nzcv[0])  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	13: begin //LE
	if(nzcv[2] == 0 || nzcv[3] != nzcv[0])  will_this_be_executed = 1;
	else will_this_be_executed = 0;	
	end	
	
	14: begin //AL
	will_this_be_executed = 1;	
	end	
	
	15: begin //reserved
	will_this_be_executed = 1;
	end

endcase


end

endmodule
module bshift(instr_bit_25,imm_value, Rm, Rs, operand2, cin, c_to_alu, direct_data, use_shifter);
	parameter n=32;
	input [n-1:0] direct_data;
	input use_shifter;
	input instr_bit_25; // bit no. 25 in the instr
	input [11:0] imm_value; // bits 11-0 in instr
	input [n-1:0] Rm;
	input [n-1:0] Rs;
	output [n-1:0] operand2; // operand 2 for ALU
	input cin;
	output reg c_to_alu;
	
	wire instr_bit_25;
	wire [11:0] imm_value;
	reg [n-1:0] in;
	reg [n-1:0] out;
	reg [7:0] shiftby; // no. bits to be shifted
	reg [n-1:0] junk;
	
	assign operand2 =(use_shifter==1)?out:direct_data ;
	
	always @* begin 
		
		if (instr_bit_25) begin
			// right rotate 32 bit zero extended imm_value[7:0] by 2*(top 4 bits of imm_value)
			in[n-1:8] = 0;
			in[7:0] = imm_value[7:0];
			shiftby[0]=0;
			shiftby[7:4]=4'd0;
			shiftby[4:1] = imm_value[11:8];
			{junk,out} = {in,in} >> shiftby[7:0];
			if(shiftby[7:0]==0) c_to_alu = cin;
			else c_to_alu = out[31];
		end
		
		else begin // 10 cases here.
			// logical shift left by Immediate. This one is for 2 cases.
			if(imm_value[6:4] == 0) begin
				in = Rm;
				{c_to_alu,out} = {cin ,in} << imm_value[11:7];
				// C flag
			end
			// logical shift left by register
			if(imm_value[6:4] == 3'd1) begin
				in = Rm;
				shiftby[7:0] = Rs[7:0];
				{c_to_alu,out} = {cin,in} << shiftby[7:0];
			
			end
			
			// logical shift right by immediate
			if(imm_value[6:4] == 3'd2) begin
				in = Rm;
				{out, c_to_alu} = {in,cin} >> imm_value[11:7];
			
			end
			
			// logical shift right by register
			if(imm_value[6:4] == 3'd3) begin
				in = Rm;
				shiftby[7:0] = Rs[7:0];
				{out, c_to_alu} = {in,cin} >> shiftby[7:0];
			
			end
			
			//Arithmetic shift right by immediate
			if(imm_value[6:4] == 3'd4) begin
				in = Rm;
				//out[7] = in[7]; // preserves sign
				if(in[n-1]){junk,out, c_to_alu} = {32'hFFFFFFFF,in,cin} >> imm_value[11:7];
				else {out, c_to_alu} = {in,cin} >> imm_value[11:7];
			end
			
			//Arithmetic Shift Right by Register
			if(imm_value[6:4] == 3'd5) begin
				in = Rm;
				shiftby[7:0] = Rs[7:0];
				if(in[n-1]) {junk,out, c_to_alu} = {32'hFFFFFFFF,in,cin} >> shiftby[7:0];
				else {out,c_to_alu} = {in,cin} >> shiftby[7:0];
			end
			
			// Rotate Right by immediate
			if((imm_value[6:4] == 3'd6)&&(imm_value[11:7]!=5'd0)) begin
				in = Rm;
				{junk,out,c_to_alu} = {in,in,cin} >> imm_value[11:7];
			end
			
			//Rotate Right by Register
			if(imm_value[6:4] == 3'd7) begin
				in=Rm;
				shiftby[7:0] = Rs[7:0];
				{junk,out,c_to_alu} = {in,in,cin} >> shiftby[4:0]; // [4:0] because.. if input is given as 100 it is enough to shift with 4 .. i.e 100mod 32
			end
			
			// RRX
			
			if((imm_value[6:4] == 3'd6)&&(imm_value[11:7]==5'd0)) begin
				in= Rm;
				{out, c_to_alu} = {cin, in};
			end
		
		end
	end
endmodule
module register_file(in_address1,in_address2,in_address3,in_address4, 
						out_data1,out_data2,out_data3,out_data4, 
						write_address,write_data,write_enable,
						write_address2, write_data2, write_enable2,
						pc, pc_update, pc_write, 
						cspr, cspr_write, cspr_update, clk );

parameter N = 32;			 //register data size 

reg [N-1:0] R [15:0];	//16, 32 bit registers

//reading
input [3:0]in_address1;
input [3:0]in_address2;
input [3:0]in_address3;
input [3:0]in_address4;
output reg [N-1:0]out_data1;
output reg [N-1:0]out_data2;
output reg [N-1:0]out_data3;
output reg [N-1:0]out_data4;

//writing
input [3:0]write_address;
input[N-1:0] write_data;
input [3:0]write_address2;
input[N-1:0] write_data2;

input clk;
input write_enable;
input write_enable2;
//pc
output reg [N-1:0]pc;
input pc_write;
input[N-1:0] pc_update;


//cspr
output reg [N-1:0]cspr;
input wire cspr_write;
input[N-1:0] cspr_update;



initial begin
	cspr = 0;
	R[0] = 0;
	R[1] = 0;
	R[2] = 0;
	R[3] = 0;
	R[4] = 0;
	R[5] = 0;
	R[6] = 0;
	R[7] = 0;
	R[8] = 0;
	R[9] = 0;
	R[10] = 0;
	R[11] = 0;
	R[12] = 0;
	R[13] = 0;
	R[14] = 0;
	R[15] = 0;	//pc = 0
end

always@(*) begin
	pc = R[2^3];
end





always@(negedge clk) begin
	out_data1=R[in_address1];
	out_data2=R[in_address2];
	out_data3=R[in_address3];
	out_data4=R[in_address4];

	if(pc_write == 1) R[15] = pc_update;
	if(cspr_write == 1) cspr = cspr_update;
	if (write_enable==1) R[write_address]=write_data;
	if (write_enable2==1) R[write_address2]=write_data2;
end

endmodule
module test;

reg clk;
DeepPipeline arm(clk);

initial
 begin
 	clk = 1;
    $dumpfile("test.vcd");
    $dumpvars(0,test);

    #1 clk = ~clk;

    #1 clk = ~clk;
    #1 clk = ~clk;
    #1 clk = ~clk;

    #1 clk = ~clk;
    #1 clk = ~clk;
    #1 clk = ~clk;
    #1 clk = ~clk;
    #1 clk = ~clk;

    #1 clk = ~clk;
    #1 clk = ~clk;
    
    #1 clk = ~clk;
    #1 clk = ~clk;
    #1 clk = ~clk;
    #1 clk = ~clk;

    #1 clk = ~clk;

#1 clk = ~clk;


#1 clk = ~clk;

#1 clk = ~clk;


#1 clk = ~clk;

#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;
#1 clk = ~clk;






 end

endmodule
module instr_cache(PC,instr,read_enable,clk);
parameter instr_size = 32;
parameter N = 32;
parameter addr_size = 8;	//pc supplies address to instr_cache, so addr_size is same as addr_width here. We ignore msb bits from r15.

reg [instr_size-1:0] M [256-1:0];	//2^addr_size-1, 32 bit instructions
input read_enable;
input [N-1:0]PC;
input clk;
output reg [instr_size-1:0] instr;

initial begin
//application code here.
M[0]= 32'he3a0000a;	
M[1]= 32'he3a00000; //MOV      r0, #10        ; Set up parameters
M[2]= 32'he3a01001;	//MOV      r1, #3
M[3] =32'he0913002;	//MOV		 r4, #4;here
M[4]= 32'he1a01002;	//MOV r9, #19
M[5]= 32'he1a02003;	//add ro,r1,#43
M[6]= 32'h3afffffb;	//MOV		 r7, #2
M[7]= 32'he3a07001;	//
M[8]= 32'he3a07002; //
M[9]= 32'he3a07002; //
M[10]= 32'he3a07003; //
M[11]= 32'he3a07004; //
M[12]= 32'he3a07005; //
M[13]= 32'he3a07006; //
M[14]= 32'he3a07007; //
M[15]= 32'he3a07008; //
M[16]= 32'he3a07009; //
M[17]= 32'he3a07001; //
end


always @ (negedge clk)	
begin
	if(read_enable==1) begin
		instr= M[PC[addr_size+1:2]];
	end
end

endmodule
module data_cache(data_address,in_data,out_data,read_enable,write_enable,clk,isByte);
parameter data_width = 8;	//size of each data read, will be of width 16, i.e, half word by default.
parameter N =32;
parameter addr_width = 12;	//It determines the number of data (half)words in memory

reg [data_width-1:0] M [2^addr_width-1:0];	//2^addr_width-1, 16 bit data
input [N-1 :0] data_address;
input read_enable;
input write_enable;
input clk;
input isByte;

output reg [N-1:0] out_data;
input [N-1 :0] in_data;

always @ (posedge read_enable, posedge write_enable)
begin
	if(read_enable)	begin
		if(isByte == 1) out_data = {24'hzzzzzz, M[data_address[addr_width-1:0]]};
		else out_data = { M[data_address[addr_width-1:0]+3], M[data_address[addr_width-1:0]+2], M[data_address[addr_width-1:0]+1] , M[data_address[addr_width-1:0]]};
	end	
	
	else if(write_enable)
	begin
		if(isByte == 1) M[data_address[addr_width-1:0]]=in_data[data_width-1:0];
		else { M[data_address[addr_width-1:0]+3], M[data_address[addr_width-1:0]+2], M[data_address[addr_width-1:0]+1] , M[data_address[addr_width-1:0]] } = in_data;
	end
end

endmodule
module register_test;

reg[3:0] read_address;
reg[3:0] write_address;

reg[31:0] write_data;
reg write_enable = 0;

reg[31:0] pc_update;
reg pc_write;

reg clk;

wire[31:0] out_data_1;
wire[31:0] cspr;
wire[31:0] pc;

register_file RegisterFile(	//inputs
							.in_address1(read_address),
							.in_address2(),
							.in_address3(),
							.in_address4(write_address),

							.universal_read_address(),
							
							.in_data(write_data),
							.write_enable(write_enable),
							.pc_update(pc_update), 
							.pc_write(pc_write), 
							.cspr_write(), 
							.cspr_update(),
							.clk(clk), 
							
							//outputs
							.out_data1(out_data_1),
							.out_data2(),
							.out_data3(),
							
							.universal_out_data(),
							
							.pc(pc), 
							.cspr(cspr)			
							
							);

initial begin
	#1 clk = 1;

	#2 clk = 0;

	#3 clk = 1;
	read_address = 0;
	
	#4 clk = 0;
	$display("pc- %h" , pc);

	#5 clk = 1;
	pc_update = pc+4;
	pc_write = 1;

	#6 clk = 0;
	$display("pc %h", pc);
end

endmodule
module SOC (
    input  wire	     CLK, // system clock 
    input  wire	     RESET,// reset button
    output reg [3:0] LEDS, // system LEDs
    output wire	     TXD  // UART transmit
);

   wire clk;
   wire resetn;
   
   wire [31:0] IO_mem_addr;
   wire [31:0] IO_mem_rdata;
   wire [31:0] IO_mem_wdata;
   wire        IO_mem_wr;

   Processor CPU(
      .clk(clk),
      .resetn(resetn),
      .IO_mem_addr(IO_mem_addr),
      .IO_mem_rdata(IO_mem_rdata),
      .IO_mem_wdata(IO_mem_wdata),
      .IO_mem_wr(IO_mem_wr)
   );

   wire [13:0] IO_wordaddr = IO_mem_addr[15:2];
   
   // Memory-mapped IO in IO page, 1-hot addressing in word address.   
   localparam IO_LEDS_bit      = 0;  // W four leds
   localparam IO_UART_DAT_bit  = 1;  // W data to send (8 bits) 
   localparam IO_UART_CNTL_bit = 2;  // R status. bit 9: busy sending
   
   always @(posedge clk) begin
      if(IO_mem_wr & IO_wordaddr[IO_LEDS_bit]) begin
	 LEDS <= IO_mem_wdata[3:0];
      end
   end

   wire uart_valid = IO_mem_wr & IO_wordaddr[IO_UART_DAT_bit];
   wire uart_ready;


   corescore_emitter_uart #(
      .clk_freq_hz(`CPU_FREQ*1000000),
          .baud_rate(1000000)
   ) UART(
      .i_clk(clk),
      .i_data(IO_mem_wdata[7:0]),
      .i_valid(uart_valid),
      .o_ready(uart_ready),
      .o_uart_tx(TXD)
   );

   assign IO_mem_rdata = 
		    IO_wordaddr[IO_UART_CNTL_bit] ? { 22'b0, !uart_ready, 9'b0}
	                                          : 32'b0;

`ifdef BENCH
   always @(posedge clk) begin
      if(uart_valid) begin
`ifdef CONFIG_DEBUG
	 $display("UART: %c", IO_mem_wdata[7:0]);
`else	 
	 $write("%c", IO_mem_wdata[7:0] );
	 $fflush(32'h8000_0001);
`endif	 
      end
   end
`endif   
   
   // Gearbox and reset circuitry.
   Clockworks CW(
     .CLK(CLK),
     .RESET(RESET),
     .clk(clk),
     .resetn(resetn)
   );

endmodule
module Clockworks 
(
   input  wire CLK,   // clock pin of the board
   input  wire RESET, // reset pin of the board
   output wire clk,   // (optionally divided) clock for the design.
                      // divided if SLOW is different from zero.
   output wire resetn // (optionally timed) negative reset for the design
);               
   parameter SLOW=0;

   generate

/****************************************************

 Slow speed mode.
 - Create a clock divider to let observe what happens.
 - Nothing special to do for reset
 
 ****************************************************/
      if(SLOW != 0) begin
	 // Factor is 1 << slow_bit.
	 // Since simulation is approx. 16 times slower than
	 // actual device we use different factor for bosh.
`ifdef BENCH
   localparam slow_bit=SLOW-4;
`else
   localparam slow_bit=SLOW;
`endif
	 reg [slow_bit:0] slow_CLK = 0;
	 always @(posedge CLK) begin
	    slow_CLK <= slow_CLK + 1;
	 end
	 assign clk = slow_CLK[slow_bit];

`ifdef NEGATIVE_RESET
	 assign resetn = RESET;
`else
	 assign resetn = !RESET;
`endif


/****************************************************

 High speed mode.
 - Nothing special to do for the clock
 - A timer that resets the design during the first
   few microseconds, because reading in Ice40 BRAM 
   during the first few microseconds returns garbage !
   (made me bang my head against the wall).
 
 ****************************************************/
	 
      end else begin 
	
`ifdef CPU_FREQ
        femtoPLL #(
          .freq(`CPU_FREQ)
        ) pll(
           .pclk(CLK),
           .clk(clk)
	);
`else
        assign clk=CLK;
`endif


// Preserve resources on Ice40HX1K (IceStick) with 
// carefully tuned counter (12 bits suffice). 
// For other FPGAs, use larger counter.
`ifdef ICE_STICK
	 reg [11:0] 	    reset_cnt = 0;
`else   
	 reg [15:0] 	    reset_cnt = 0;
`endif   
	 assign resetn = &reset_cnt;

`ifdef NEGATIVE_RESET
	 always @(posedge clk,negedge RESET) begin
	    if(!RESET) begin
	       reset_cnt <= 0;
	    end else begin
	       reset_cnt <= reset_cnt + !resetn;
	    end
	 end
`else   
	 always @(posedge clk,posedge RESET) begin
	    if(RESET) begin
	       reset_cnt <= 0;
	    end else begin
	       /* verilator lint_off WIDTH */
	       reset_cnt <= reset_cnt + !resetn;
	       /* verilator lint_on WIDTH */	       
	    end
	 end
`endif   
      end
   endgenerate

endmodule
module OneShot(
    input pulse,
    input clk,
    input rst,
    output reg out
    );
initial out = 0;
parameter waiting_l = 2'b00, on = 2'b01, waiting_h = 2'b10;
reg[1:0] next_state, current_state;

always @ (posedge clk or posedge rst) begin
	if(rst) begin
		current_state <= waiting_l;
	end
	else begin
		current_state <= next_state;
	end
end

always @ (current_state or pulse) begin
	if(current_state == on) begin
		next_state <= waiting_h;
	end
	else if(current_state == waiting_h) begin
		if(pulse) begin
			next_state <= waiting_h;
		end
		else begin
			next_state <= waiting_l;
		end
	end
	else if(pulse) begin
		next_state<= on;
	end
	else begin
		next_state<= waiting_l;
	end
end

always @(current_state or rst) begin
	if(rst)
		out <= 1'b0;
	else if(current_state == on)
		out <= 1'b1;
	else 
		out <= 1'b0;
end








endmodule
module tx_test;

	// Inputs
	wire rx;
	reg [10:0] address;
	reg clk;
	reg baud_clk;
	reg rst;
	reg [63:0] data;
	reg send_data;
	reg rxing;

	// Outputs
	wire tx;

	// Instantiate the Unit Under Test (UUT)
	tx_container uut (
		.tx(tx), 
		.txing(txing),
		.rx(rx), 
		.rxing(rxing),
		.address(address), 
		.clk(clk),
		.baud_clk(baud_clk),
		.rst(rst), 
		.data(data), 
		.send_data(send_data)
	);
	
	

	assign rx = tx;
	
	initial begin
		// Initialize Inputs
		address = 11'h28;
		rxing = 0;
		clk = 1'b0;
		baud_clk = 1'b0;
		rst = 1'b1;
		//data = 64'hAAAAAAAAAAAAAAAA;
		data = 64'hA83;
		send_data = 1'b0;
		
		// Add stimulus here
		#100 rst = 0;

		#101 send_data = 1'b1;
		#3000 send_data = 1'b0;
		#310000 $stop;
	end
		always #1.25 clk=~clk;
		always #1000 baud_clk=~baud_clk;
endmodule
module shift_reg(
    input rx,
    output reg[(reg_length-1):0] shifted_bus,
	output reg finished_rx,
    input rst,
    input baud_clk
    );
	
	parameter reg_length = 150;

	initial finished_rx = 0;
	parameter idle = 2'b00, reading = 2'b01, finished = 2'b10, finished_and_waiting = 2'b11;
	reg[1:0] current_state, next_state;
	
	reg [(reg_length-1):0] bitShiftReg = {reg_length{1'b1}};

	always @(posedge baud_clk or posedge rst) begin
		if(rst) begin
			bitShiftReg <= {reg_length{1'b1}};
			current_state <=  idle;
		end
		else begin
			current_state <= next_state;
			bitShiftReg <= {bitShiftReg[(reg_length-2):0],rx};
		end
	end
	always @(rx or bitShiftReg or current_state) begin
		case(current_state) 
			idle: begin
				if(rx == 1)
					next_state <= idle;
				else 
					next_state <= reading;
				end
			reading: begin
				if(bitShiftReg[6:0] == {7{1'b1}})
					next_state <= finished;
				else
					next_state <= reading;
				end
			finished: begin
				next_state<= finished_and_waiting;
			end
			
			default: begin
				next_state<=idle;
			end
		endcase
	end
	
	always @ (current_state) begin
		if(current_state == finished)
			finished_rx <= 1;
		else
			finished_rx <= 0;
	end
	
	always @ (posedge finished_rx or posedge rst) begin
		if(rst) 
			shifted_bus <= {reg_length{1'b1}};
		else
			shifted_bus <= bitShiftReg;
	end

endmodule
module CANIPCORETEST;

	// Inputs
	reg can_clk;
	reg can_phy_rx;
	reg bus2ip_reset;
	reg bus2ip_rnw;
	reg bus2ip_cs;
	reg sys_clk;
	reg [0:5] bus2ip_addr;
	reg [0:31] bus2ip_data;

	// Outputs
	wire ip2bus_intrevent;
	wire ip2bus_error;
	wire ip2bus_ack;
	wire can_phy_tx;
	wire [0:31] ip2bus_data;

	// Instantiate the Unit Under Test (UUT)
	CAN_BUS_Model uut (
		.can_phy_rx(can_phy_rx), 
		.can_clk(can_clk), 
		.bus2ip_reset(bus2ip_reset), 
		.ip2bus_intrevent(ip2bus_intrevent), 
		.bus2ip_rnw(bus2ip_rnw), 
		.bus2ip_cs(bus2ip_cs), 
		.ip2bus_error(ip2bus_error), 
		.sys_clk(sys_clk), 
		.ip2bus_ack(ip2bus_ack), 
		.can_phy_tx(can_phy_tx), 
		.ip2bus_data(ip2bus_data), 
		.bus2ip_addr(bus2ip_addr), 
		.bus2ip_data(bus2ip_data)
	);

	initial begin
		// Initialize Inputs
		can_clk = 0;
		bus2ip_reset = 1;
		bus2ip_rnw = 1;
		bus2ip_cs = 0;
		sys_clk = 0;
		bus2ip_addr = 6'd3;
		bus2ip_data = 32'd42;
		can_phy_rx = 1;

		// Wait 100 ns for global reset to finish
		#100;
		bus2ip_reset = 0;
		#10;
		bus2ip_data = 32'd42;
		bus2ip_addr = 6'd3;
		#10;
        bus2ip_cs = 1;
		bus2ip_rnw = 0;
		#50
		bus2ip_cs = 0;
		bus2ip_rnw = 1;
		
		// Add stimulus here

	end
	
	always #5 sys_clk=~sys_clk;
    always #25 can_clk=~can_clk;
endmodule
module tx_container(
	output reg tx,
	output txing,
	input rx,
	input rxing,
	input[10:0] address,
	input clk,
	input baud_clk,
	input rst,
	input [63:0] data,
	input send_data
    );


	parameter  init = 2'h0,  ones = 2'h1, zeros = 2'h2;
	assign clear_to_tx =1;
	reg bit_stuffing = 0;
	reg[1:0] c_state=0, n_state=0, p_state = 0;
	reg[31:0] bit_stuffing_count = 0;
	wire can_bitstuff;
	
	can_tx tx_block(tx_buf,can_bitstuff,txing,rx,address,clk,baud_clk,rst,data,send_data,tx,clear_to_tx);

	always @ (posedge clk or posedge rst) begin
		if(rst) begin
			bit_stuffing_count<= 0;
			bit_stuffing <= 0;
		end
		else begin
			if(n_state != c_state) begin
				bit_stuffing_count<= 0;
				bit_stuffing <= 0;
			end
			else if(!can_bitstuff) begin
				bit_stuffing_count <= 0;
				bit_stuffing <= 0;
			end 
			else if(bit_stuffing_count >= 5000)begin
				bit_stuffing_count <= 0;
				bit_stuffing <= 0;
			end
			else if(bit_stuffing_count >= 4000)begin
				bit_stuffing_count <= bit_stuffing_count + 1;
				bit_stuffing <= 1;
			end
			else begin
				bit_stuffing_count <= bit_stuffing_count +1;
				bit_stuffing <= 0;
			end
		end
	end

	always @ (posedge clk) begin
		c_state <= n_state;
	end

	always @ (tx_buf) begin
		if(tx_buf == 1) begin
			n_state<= ones;
		end
		else begin
			n_state <= zeros;
		end
	end

	always @ (bit_stuffing or tx_buf) begin
		if(bit_stuffing) begin
			tx <= ~tx_buf;
		end
		else begin
			tx <= tx_buf;
		end
	end
endmodule
module BaudGen(clk,rst,baud_clk);
input clk,rst;
output reg baud_clk;

//EndCount is equal to clk frequency/baud frequency
// Therefore 400MHz/500kHz = 800
parameter EndCount = 10'd800;
reg[9:0] count = 0;

always@(posedge clk)begin
	if(rst == 1) begin
		count <=10'd0;
		baud_clk <= 10'd0;
	end
	else if(count == EndCount) begin
		count <= 10'd0; 
		baud_clk <= ~baud_clk;
		end
	else begin
		count <= count + 10'd1;
		baud_clk <= baud_clk;
		end
	end

endmodule
module Tx_test_internal;

	// Inputs
	reg [10:0] address;
	reg clk;
	reg baud_clk;
	reg rst;
	reg [63:0] data;
	reg send_data;
	reg clear_to_tx;
	assign rx = tx;
	assign bitstuffed_output = tx;

	// Outputs
	wire tx;
	wire can_bitstuff;
	wire txing;

	// Instantiate the Unit Under Test (UUT)
	can_tx uut (
		.tx(tx), 
		.can_bitstuff(can_bitstuff), 
		.txing(txing), 
		.rx(rx), 
		.address(address), 
		.clk(clk), 
		.baud_clk(baud_clk), 
		.rst(rst), 
		.data(data), 
		.send_data(send_data), 
		.bitstuffed_output(bitstuffed_output), 
		.clear_to_tx(clear_to_tx)
	);

	initial begin
		// Initialize Inputs
		address = 11'h28;
		clk = 0;
		baud_clk = 0;
		rst = 1;
		data = 43;
		send_data = 0;
		clear_to_tx = 0;

		// Wait 100 ns for global reset to finish
		#100;
        rst = 0;
		#10;
		send_data = 1;
		clear_to_tx = 1;
		#300000 $stop;
		// Add stimulus here

	end
	always #1.25 clk=~clk;
	always #1000 baud_clk=~baud_clk;
      
endmodule
module Main(
	output CAN_TX,
	input CAN_RX,
	input RESET,
	input CLOCK_SIGNAL_IN,
	input send_data,
	input[7:0] transmit_data
	);
	
	wire[63:0] tx_data;
	wire txing;
	
	assign tx_data = {8{transmit_data}};
	
	//Device address, arbitrarily chosen
	parameter address = 11'h25, rxing = 1'b1;
	
	//Clock Generator (100MHz in, 400MHz out)
	Clock_gen clock_block(CLOCK_SIGNAL_IN,clk);
	
	//Baud Clk Generator(currently set for baud of 500kHz)
	BaudGen baud_calc(clk,RESET,baud_clk);

	
	//Tx Block
	//can_tx tx_block(CAN_TX,CAN_RX,address,clk,baud_clk,RESET,tx_data,send_data);
	tx_container tx_can(CAN_TX,txing,CAN_RX,rxing,address,clk,baud_clk,RESET,tx_data,send_data);
	//rx_container rx_can(rx_data,rxing,txing,CAN_RX,clk,baud_clk,RESET);
	
	//Rx goes here

	
endmodule
module Main_test;

	// Inputs
	assign CAN_RX = CAN_TX;
	reg RESET;
	reg CLOCK_SIGNAL_IN;
	reg send_data;
	reg [7:0] transmit_data;
	// Outputs
	wire CAN_TX;

	// Instantiate the Unit Under Test (UUT)
	Main uut (
		.CAN_TX(CAN_TX), 
		.CAN_RX(CAN_RX), 
		.RESET(RESET), 
		.CLOCK_SIGNAL_IN(CLOCK_SIGNAL_IN), 
		.send_data(send_data), 
		.transmit_data(transmit_data)
	);

	initial begin
		// Initialize Inputs
		RESET = 1;
		CLOCK_SIGNAL_IN = 0;
		send_data = 0;
		transmit_data = 8'b11100011;

		// Wait 100 ns for global reset to finish
		#100;
		#100 RESET = 0;
		#1000 send_data = 1;
		#100000 $stop;
		
        
		// Add stimulus here
	end
     
	 always #10 CLOCK_SIGNAL_IN = ~CLOCK_SIGNAL_IN;
endmodule
module OneShotTest;

	// Inputs
	reg pulse;
	reg clk;
	reg rst;

	// Outputs
	wire out;

	// Instantiate the Unit Under Test (UUT)
	OneShot uut (
		.pulse(pulse), 
		.clk(clk), 
		.rst(rst), 
		.out(out)
	);

	initial begin
		// Initialize Inputs
		pulse = 0;
		clk = 0;
		rst = 1;

		// Wait 100 ns for global reset to finish
		#100;
        rst = 0;
		#10;
		pulse = 1;
		#100; $stop;
		// Add stimulus here

	end
	always #1.25 clk=~clk;
      
endmodule
module BitshiftTest;

	// Inputs
	reg rx;
	reg rst;
	reg baud_clk;

	// Outputs
	wire [149:0] shifted_bus;

	// Instantiate the Unit Under Test (UUT)
	shift_reg uut (
		.rx(rx), 
		.shifted_bus(shifted_bus),
		.finished_rx(finished_rx),
		.rst(rst), 
		.baud_clk(baud_clk)
	);

	initial begin
		// Initialize Inputs
		rx = 1'b1;
		rst = 1;
		baud_clk = 0;
		#10 rst = 1'b0;
		
		#1000 rx = 1'b0;
		#12000 rx = 1'b1;
		#2000 rx = 1'b0;
		#2000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#4100 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#2000 rx = 1'b0;
		#2000 rx = 1'b1;
		#2000 rx = 1'b0;
		#2000 rx = 1'b1;
		#2000 rx = 1'b0;
		#10000 rx = 1'b1;
		#6000 rx = 1'b0;
		#2000 rx = 1'b1;
		#10000 rx = 1'b0;
		#6000 rx = 1'b1;
		#70000; $stop;
		
	end
	
	
	always #1000 baud_clk=~baud_clk;
      
endmodule
module layer_1(
    input                 sys_clk     ,
    input                 sys_rst_n   ,
    input                 start_flag  ,

    output    [32:0]      data_out    ,
    output                out_valid
    );

    wire        [15:0]      data_pic        ;
    wire                    pic_valid       ;

pic_input   pic_generate(
    .clk            (sys_clk        ),
    .rst_n          (sys_rst_n      ),
    .pic_start      (start_flag     ),

    .pic_out_valid  (pic_valid      ),
    .data_pic       (data_pic       )
);
conv    conv_1_1(
    .clk            (sys_clk        ),
    .rst_n          (sys_rst_n      ),
    .data_pic       (data_pic       ),
    .pic_valid      (pic_valid      ),

    .data_out       (data_out       ),
    .out_valid      (out_valid      )
);
endmodule
module vga(
    input           clk         ,
    input           rst_n       ,

    input   [23:0]  data        ,

    output          hs          ,
    output          vs          ,

    output  [ 9:0]  x_pix       ,
    output  [ 9:0]  y_pix       ,
	
    output  [23:0]  color_rgb
);

parameter   h_sync = 'd96   ;
parameter   h_back = 'd40   ;
parameter   h_left = 'd8    ;
parameter   h_vali = 'd640  ;
parameter   h_righ = 'd8    ;
parameter   h_fron = 'd8    ;
parameter   h_peri = 'd800  ;

parameter   v_sync = 'd2    ;
parameter   v_back = 'd25   ;
parameter   v_topb = 'd8    ;
parameter   v_vali = 'd480  ;
parameter   v_unde = 'd8    ;
parameter   v_fron = 'd2    ;
parameter   v_peri = 'd525  ;

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

wire            h_en        ;
wire            v_en        ;

always @ (posedge clk or negedge rst_n)begin
    if (!rst_n)begin
        h_count <= 10'd0;
        v_count <= 10'd0;
    end
    else if(h_count < h_peri)
        h_count <= h_count + 1'b1;
    else begin
        h_count <= 10'd0;
        if (v_count < v_peri)
            v_count <= v_count + 1'b1;
        else
            v_count <= 10'd0;
    end
end

assign hs = (h_count > 'd0 && h_count < h_sync) ? 1'b0 : 1'b1;
assign vs = (v_count > 'd0 && v_count < v_sync) ? 1'b0 : 1'b1;

assign h_en = (h_count > h_sync + h_back + h_left && h_count < h_sync + h_back + h_left + h_vali) ? 1'b1 : 1'b0;
assign v_en = (v_count > v_sync + v_back + v_topb && v_count < v_sync + v_back + v_topb + v_vali) ? 1'b1 : 1'b0;

assign x_pix = h_en ? h_count - h_sync - h_back - h_left : 10'b0;
assign y_pix = v_en ? v_count - v_sync - v_back - v_topb : 10'b0;

assign color_rgb = h_en && v_en ? data : 24'd0;
endmodule
module layer_2(
    input                 sys_clk     ,
    input                 sys_rst_n   ,
    input                 start_flag  ,

    output    [32:0]      data_out    ,
    output                out_valid
    );

    wire        [32:0]      data_max_out        ;
    wire                    data_max_valid      ;

max_data_generate   max_data_generate(
    .clk            (sys_clk        ),
    .rst_n          (sys_rst_n      ),
    .data_start     (start_flag     ),

    .data_out_valid (data_max_valid ),
    .data_out       (data_max_out   )
);
maxpooling    maxpooling_inst(
    .clk            (sys_clk        ),
    .rst_n          (sys_rst_n      ),
    .input_data     (data_max_out   ),
    .valid_input    (data_max_valid ),

    .out_data       (data_out       ),
    .out_valid      (out_valid      )
);
endmodule
module pic_input(
    input           clk             ,
    input           rst_n           ,
    input           pic_start       ,

    output          pic_out_valid   ,
    output  [15:0]  data_pic
    );

    wire    [15:0]      data_pic_out        ;

    reg     [15:0]      data_pic_reg        ;
    reg     [ 9:0]      addr_pic            ;
    reg                 work_en_pic         ;
    reg                 pic_out_valid_reg   ;

always @ (posedge clk or negedge rst_n)begin
    if (!rst_n)
        data_pic_reg <= 16'b0;
    else if (data_pic_out)
        data_pic_reg <= data_pic_out;
    else
        data_pic_reg <= data_pic_reg;
end

always @ (posedge clk or negedge rst_n)begin
    if (!rst_n)
        pic_out_valid_reg <= 1'b0;
    else if (work_en_pic && addr_pic == 9'd1)
        pic_out_valid_reg <= 1'b1;
    else if (addr_pic == 10'd784)
        pic_out_valid_reg <= 1'b0;
    else
        pic_out_valid_reg <= pic_out_valid_reg;
end

always @ (posedge clk or negedge rst_n)begin
    if (!rst_n)
        addr_pic <= 10'b0;
    else if (work_en_pic && addr_pic == 10'd784)
        addr_pic <= 10'd784;
    else if (work_en_pic)
        addr_pic <= addr_pic + 1'b1;
    else
        addr_pic <= addr_pic;
end

always @ (posedge clk or negedge rst_n)begin
    if (!rst_n)
        work_en_pic <= 1'b0;
    else if (pic_start)
        work_en_pic <= 1'b1;
    else if (addr_pic == 10'd784)
        work_en_pic <= 1'b0;
end

assign  data_pic = data_pic_reg;
assign  pic_out_valid = pic_out_valid_reg;

rom_0_388 rom_pic(
    .clka   (clk            ),
    .addra  (addr_pic       ),
    .douta  (data_pic_out   )
);
endmodule