data/full_repos/permissive/516181732/src/spi_driver.v
data/verilator_xmls/bb681660-8278-47a9-9865-bbcdd4e5a30a.xml
module spi_driver
	#(
		parameter SPI_MODE = 0,
		parameter CLKS_PER_HALF_BIT = 2
	)
  	(

		input wire rst_n,
		input wire clk_in,

		input wire [7:0]mosi_data,
		input wire mosi_trigger,
		output reg mosi_ready,

		output reg miso_ready,
		output reg [7:0]miso_data,

		output reg spi_clk,
		output reg spi_mosi,
		input wire spi_miso
	);


	wire CPOL;
	wire CPHA;

	reg [$clog2(CLKS_PER_HALF_BIT*2)-1:0] spi_clk_count;
	reg 		r_spi_clk;
	reg [4:0] 	spi_clk_edges;
	reg 		leading_edge;
	reg			trailing_edge;
	reg			r_mosi_trigger;
	reg [7:0]	r_mosi_data;

	reg [2:0] 	miso_bit_count;
	reg [2:0] 	mosi_bit_count;




	assign CPOL = (SPI_MODE == 2) | (SPI_MODE == 3);






	assign CPHA = (SPI_MODE == 1) | (SPI_MODE == 3);



	always @(posedge clk_in or negedge rst_n) begin
	
		if ( ~rst_n ) begin
			mosi_ready <= 1'b0;
			spi_clk_edges <= 0;
			leading_edge <= 1'b0;
			trailing_edge <= 1'b0;
			r_spi_clk <= CPOL;
			spi_clk_count <= 0;
		end else begin


			leading_edge <= 1'b0;
			trailing_edge <= 1'b0;
      
			if ( mosi_trigger ) begin
				mosi_ready <= 1'b0;
				spi_clk_edges <= 16;
			end else if ( spi_clk_edges > 0 ) begin
				mosi_ready <= 1'b0;
        	
				if ( spi_clk_count == CLKS_PER_HALF_BIT * 2 - 1 ) begin
					spi_clk_edges <= spi_clk_edges - 1;
					trailing_edge <= 1'b1;
					spi_clk_count <= 0;
					r_spi_clk <= ~r_spi_clk;
				end else if ( spi_clk_count == CLKS_PER_HALF_BIT - 1 ) begin
					spi_clk_edges <= spi_clk_edges - 1;
					leading_edge <= 1'b1;
					spi_clk_count <= spi_clk_count + 1;
					r_spi_clk <= ~r_spi_clk;
				end else begin
					spi_clk_count <= spi_clk_count + 1;
				end
			end else begin
				mosi_ready <= 1'b1;
			end
			
		end
	end




	always @(posedge clk_in or negedge rst_n) begin
		if ( ~rst_n ) begin
			r_mosi_data <= 8'h00;
			r_mosi_trigger <= 1'b0;
		end else begin
			r_mosi_trigger <= mosi_trigger;
			if ( mosi_trigger ) begin
				r_mosi_data <= mosi_data;
			end
		end
	end




	always @(posedge clk_in or negedge rst_n) begin
		if ( ~rst_n ) begin
			spi_mosi <= 1'b0;
			mosi_bit_count <= 3'b111;
		end else begin

			if ( mosi_ready ) begin
				mosi_bit_count <= 3'b111;
			end else if ( r_mosi_trigger & ~CPHA ) begin
				spi_mosi <= r_mosi_data[3'b111];
				mosi_bit_count <= 3'b110;
			end else if ( ( leading_edge & CPHA ) | ( trailing_edge & ~CPHA ) ) begin
				mosi_bit_count <= mosi_bit_count - 1;
				spi_mosi <= r_mosi_data[mosi_bit_count];
			end
		end
	end



	always @(posedge clk_in or negedge rst_n) begin
		if ( ~rst_n ) begin
			miso_data <= 8'h00;
			miso_ready <= 1'b0;
			miso_bit_count <= 3'b111;
		end else begin

			miso_ready <= 1'b0;

			if ( mosi_ready ) begin
				miso_bit_count <= 3'b111;
			end else if ( ( leading_edge & ~CPHA ) | ( trailing_edge & CPHA ) ) begin
				miso_data[miso_bit_count] <= spi_miso;
				miso_bit_count <= miso_bit_count - 1;
				if ( miso_bit_count == 3'b000 ) begin
					miso_ready <= 1'b1;
				end
			end
		end
	end
  
  

	always @(posedge clk_in or negedge rst_n) begin
		if ( ~rst_n ) begin
			spi_clk <= CPOL;
		end else begin
			spi_clk <= r_spi_clk;
		end
	end
  

endmodule
module spi_driver
	#(
		parameter SPI_MODE = 0,
		parameter CLKS_PER_HALF_BIT = 2
	)
  	(

		input wire rst_n,
		input wire clk_in,

		input wire [7:0]mosi_data,
		input wire mosi_trigger,
		output reg mosi_ready,

		output reg miso_ready,
		output reg [7:0]miso_data,

		output reg spi_clk,
		output reg spi_mosi,
		input wire spi_miso
	);



	wire CPOL;
	wire CPHA;

	reg [$clog2(CLKS_PER_HALF_BIT*2)-1:0] spi_clk_count;
	reg 		r_spi_clk;
	reg [4:0] 	spi_clk_edges;
	reg 		leading_edge;
	reg			trailing_edge;
	reg			r_mosi_trigger;
	reg [7:0]	r_mosi_data;

	reg [2:0] 	miso_bit_count;
	reg [2:0] 	mosi_bit_count;




	assign CPOL = (SPI_MODE == 2) | (SPI_MODE == 3);






	assign CPHA = (SPI_MODE == 1) | (SPI_MODE == 3);



	always @(posedge clk_in or negedge rst_n) begin
	
		if ( ~rst_n ) begin
			mosi_ready <= 1'b0;
			spi_clk_edges <= 0;
			leading_edge <= 1'b0;
			trailing_edge <= 1'b0;
			r_spi_clk <= CPOL;
			spi_clk_count <= 0;
		end else begin


			leading_edge <= 1'b0;
			trailing_edge <= 1'b0;
      
			if ( mosi_trigger ) begin
				mosi_ready <= 1'b0;
				spi_clk_edges <= 16;
			end else if ( spi_clk_edges > 0 ) begin
				mosi_ready <= 1'b0;
        	
				if ( spi_clk_count == CLKS_PER_HALF_BIT * 2 - 1 ) begin
					spi_clk_edges <= spi_clk_edges - 1;
					trailing_edge <= 1'b1;
					spi_clk_count <= 0;
					r_spi_clk <= ~r_spi_clk;
				end else if ( spi_clk_count == CLKS_PER_HALF_BIT - 1 ) begin
					spi_clk_edges <= spi_clk_edges - 1;
					leading_edge <= 1'b1;
					spi_clk_count <= spi_clk_count + 1;
					r_spi_clk <= ~r_spi_clk;
				end else begin
					spi_clk_count <= spi_clk_count + 1;
				end
			end else begin
				mosi_ready <= 1'b1;
			end
			
		end
	end




	always @(posedge clk_in or negedge rst_n) begin
		if ( ~rst_n ) begin
			r_mosi_data <= 8'h00;
			r_mosi_trigger <= 1'b0;
		end else begin
			r_mosi_trigger <= mosi_trigger;
			if ( mosi_trigger ) begin
				r_mosi_data <= mosi_data;
			end
		end
	end




	always @(posedge clk_in or negedge rst_n) begin
		if ( ~rst_n ) begin
			spi_mosi <= 1'b0;
			mosi_bit_count <= 3'b111;
		end else begin

			if ( mosi_ready ) begin
				mosi_bit_count <= 3'b111;
			end else if ( r_mosi_trigger & ~CPHA ) begin
				spi_mosi <= r_mosi_data[3'b111];
				mosi_bit_count <= 3'b110;
			end else if ( ( leading_edge & CPHA ) | ( trailing_edge & ~CPHA ) ) begin
				mosi_bit_count <= mosi_bit_count - 1;
				spi_mosi <= r_mosi_data[mosi_bit_count];
			end
		end
	end



	always @(posedge clk_in or negedge rst_n) begin
		if ( ~rst_n ) begin
			miso_data <= 8'h00;
			miso_ready <= 1'b0;
			miso_bit_count <= 3'b111;
		end else begin

			miso_ready <= 1'b0;

			if ( mosi_ready ) begin
				miso_bit_count <= 3'b111;
			end else if ( ( leading_edge & ~CPHA ) | ( trailing_edge & CPHA ) ) begin
				miso_data[miso_bit_count] <= spi_miso;
				miso_bit_count <= miso_bit_count - 1;
				if ( miso_bit_count == 3'b000 ) begin
					miso_ready <= 1'b1;
				end
			end
		end
	end
  
  

	always @(posedge clk_in or negedge rst_n) begin
		if ( ~rst_n ) begin
			spi_clk <= CPOL;
		end else begin
			spi_clk <= r_spi_clk;
		end
	end
  

endmodule