⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial_segment.v

📁 在开发FPGA上比较有用
💻 V
字号:
module serial_segment(clk,rst_n,cs_n,rd_n,wr_n,addr,rdata,wdata,s_clk,s_dat);

// parameters
parameter PRESCALE = 16'd5; // asynchronous reset level
parameter HOLDCOUNT = 32'd125000;// hold count

	
input clk;		// master clk
input rst_n;	// reset
input cs_n;		// chip select
input rd_n;		// read signal
input wr_n;		// write signal
input [2:0]addr;// address
output [7:0]rdata;	// out data
input  [7:0]wdata;	// in  data

reg [7:0] rdata;

output s_clk;	// serial clock
output s_dat;	// serial data

//
// variable declarations
//

// state machine
	parameter IDLE  = 2'b00;
	parameter START = 2'b01;
	parameter STOP  = 2'b10;
	parameter HOLD  = 2'b11;

// registers
reg [7:0] data[3:0];	// segment data

// generate write signals
wire wacc = ~cs_n & ~wr_n;

// generate read signals
wire racc = ~cs_n & ~rd_n;
reg [7:0] trans_data;

// generate registers
always @(posedge clk or negedge rst_n)
	if (!rst_n)
	begin
	   data[0] <= #1 8'h00;
	   data[1] <= #1 8'h00;
	   data[2] <= #1 8'h00;
		data[3] <= #1 8'h00;
	end
	else
	    if ( wacc )
		begin
		  case (wdata)
			8'h0:trans_data = 8'hc0;
			8'h1:trans_data = 8'hf6;
			8'h2:trans_data = 8'h4a;
			8'h3:trans_data = 8'h52;
			8'h4:trans_data = 8'h74;
			8'h5:trans_data = 8'h51;
			8'h6:trans_data = 8'h41;
			8'h7:trans_data = 8'hf0;
			8'h8:trans_data = 8'h40;
			8'h9:trans_data = 8'h50;
			8'ha:trans_data = 8'h60;
			8'hb:trans_data = 8'h45;
			8'hc:trans_data = 8'hc9;
			8'hd:trans_data = 8'h46;
			8'he:trans_data = 8'h49;
			8'hf:trans_data = 8'h69;
			default: trans_data = wdata;
		  endcase
		
	      case ( addr ) // synopsis parallel_case
			3'b000 : data[0] <= #1 trans_data;
			3'b001 : data[1] <= #1 trans_data;
			3'b010 : data[2] <= #1 trans_data;
			3'b011 : data[3] <= #1 trans_data;	         
			default: ;
	      endcase
		end

	always @(posedge clk)
	begin
	if( racc )
	  case (addr) // synopsis parallel_case
	    3'b000: rdata <= #1 data[0];
	    3'b001: rdata <= #1 data[1];
	    3'b010: rdata <= #1 data[2];
	    3'b011: rdata <= #1 data[3]; 
	    3'b100: rdata <= #1 8'h4;  	// reserved
	    3'b101: rdata <= #1 8'h5;	// reserved
	    3'b110: rdata <= #1 8'h6;	// reserved
	    3'b111: rdata <= #1 8'h7;   // reserved
	  endcase
	end

	reg [3:0] state;		// machine state 
	reg [15:0]prescale;		// prescale 
	reg [1:0] index;		// memory index
	wire busy;				// busy 
	reg shift_start;		// shift start
	reg [3:0] sig_num;		// 
	reg [31:0]hold_count;	// hold count
	
	always @(posedge clk)
	if(~rst_n)
		begin
			state <= #1 START;
			prescale <= #1 PRESCALE;
			hold_count <=#1 HOLDCOUNT;
			shift_start <= #1 1'b0;
			index   <= #1 2'b00;
			sig_num <= #1 4'b0111;
		end
	else
		begin
			if(~busy)
			begin
				case(state)
					START: 
						begin
							state <= #1 STOP;
							shift_start <= #1 1'b1;
							index <= #1 index + 2'b01;
							
							case (index)
								2'b00: sig_num <= #1 4'b1011;
								2'b01: sig_num <= #1 4'b1101;
								2'b10: sig_num <= #1 4'b1110;
								2'b11: sig_num <= #1 4'b0111;
							endcase
						end
					STOP: 
						begin
							state <= #1 HOLD;
							hold_count <= #1 HOLDCOUNT;
							shift_start <= #1 1'b0;
						end
					HOLD:
						begin
							if(~(|hold_count))
							begin
								state <= #1 START;
								hold_count <= #1 HOLDCOUNT;
							end	
							else
								hold_count <= #1 hold_count - 32'h1;
						end
				endcase
			end		
		end
		
	wire [15:0]shift_data ={ 4'b1111,sig_num[3:0],data[index]};
	shift_bit the_shift_bit(clk,rst_n,prescale,shift_data,shift_start,busy,s_clk,s_dat);


endmodule


// 移位发送模块
// shift_start上升沿触发一次16bit的数据发送
// busy 模块忙信号输出
module shift_bit(clk,rst_n,prescale,data,start,busy,s_clk,s_dat);
input clk;			// master clk
input rst_n;		// reset 
input [15:0]prescale;// prescale
input [15:0]data;	// shift data
input start;		// rising edge 
output busy;		// busy status

output s_clk;		// serial clock
output s_dat;		// serial data

reg busy;
reg s_clk;
reg s_dat;

parameter IDLE = 5'b00001,
		  PREPARE_DATA = 5'b00010,
		  RISE_CLK = 5'b00100,
		  FALL_CLK = 5'b01000,
		  END   = 5'b10000;
		  
reg [4:0]state;		// state machine
reg [3:0]send_count;// send count
reg [15:0]wait_count;//wait count

reg [15:0]shift_data;	// shift data
reg s_start,d_start;// asynchronous start,delay start


always @(posedge clk)
if(~rst_n)
	begin
		s_start <= #1 1'b0;
		d_start <= #1 1'b0;
	end
else
	begin
		d_start <= #1 s_start;
		s_start <= #1 start;
	end

wire shift_start = ~d_start & s_start;
wire switch = |wait_count; //wait_count ==0 ?

always @(posedge clk)
if(!rst_n)
	begin
		state <=#1 IDLE;
		s_clk <=#1 1'b0;
		s_dat <=#1 1'b0;
		send_count <= #1 4'b0000;
		busy <=#1 1'b0;
		wait_count <= #1 prescale;
	end
 else
    begin
       if(shift_start)
          busy <= #1 1'b1;
       if(~switch)
	   begin
		   wait_count <= #1 prescale;
		
		   case (state)
			IDLE:
				begin
					if(busy) begin
						state <= #1 PREPARE_DATA;
						shift_data <= #1 data;
						send_count <= #1 4'b0000;
					end
					else
						state <= #1 IDLE;
				end
			PREPARE_DATA:
				begin
					s_dat <= #1 shift_data[0];
					state <= #1 RISE_CLK;
					shift_data <= #1 {1'b0,shift_data[15:1]};
				end
			RISE_CLK:
				begin
					s_clk <= #1 1'b1;
					state <= #1 FALL_CLK;
				end
			FALL_CLK:
				begin
					s_clk <= #1 1'b0;
					state <= #1 END;
				end
			END:
			   begin
					send_count <= send_count + 4'b0001;
					if ( send_count == 4'b1111)
						begin
							state <= #1 IDLE;
							busy <= #1 1'b0;
						end
					else
						state <= #1 PREPARE_DATA;
				end
		   endcase
	   end
	   else
		   wait_count <= wait_count - 16'h0001;
	end
		
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -