Click Here To Return:

Verilog source code-24'bit encoder:


//========================================================
//
//  encoder functions
//
//  Written by:
//             Kenneth Maxon 16/Mar/04
//
//========================================================

module encoder_func(
 	input wire sys_clock,
	output reg [7:0] encoder_data_out,
	input wire [1:0] proc_addr,
	input wire strobe,
	input wire reset,
	input wire encoder_a,
	input wire encoder_b
	);

// ------------------------------------parameters

parameter[3:0]
			ENC_A = 2'b00,
			ENC_B = 2'b01,
			ENC_C = 2'b10,
			ENC_D = 2'b11;

parameter[3:0]
			STATE_A = 4'b0001,
			STATE_B = 4'b0010,
			STATE_C = 4'b0100,
			STATE_D = 4'b1000;

parameter[3:0]
			CASE_A = 4'bxxx1,
			CASE_B = 4'bxx1x,
			CASE_C = 4'bx1xx,
			CASE_D = 4'b1xxx;

// ------------------------------------local var

reg [23:0] counter;
reg [23:0] latched_val;
reg [3:0] enc_state;
reg encoder_reg_a;
reg encoder_reg_b;
wire [1:0] encoders = {encoder_reg_a,encoder_reg_b};  //grouped together

// register signals crossing clock domains.

always @(posedge sys_clock)
begin
	encoder_reg_a <= #1 encoder_a;
	encoder_reg_b <= #1 encoder_b;
end

// THE ENCODER COUNT IS LATCHED INTO AN OUTPUT VARIABLE AND HELD
//   WHEN THE LSB'S ARE READ.  THIS ASSURES THE COUNT WILL NOT
//   CHANGE BETWEEN READING THE LOWER AND UPPER BITS.  TO ALLOW
//   THIS FUNCTIONALITY, THE LSB'S MUST ALWAYS BE READ FIRST.  IF
//   THE UPPER BITS MUST BE READ FIRST, THEN CHNAGE THE ADDRESS
//   IN THE ELSE IF STATEMENT BELOW TO MATCH THE FIRST READ BITS.

always @(posedge sys_clock or posedge reset)
	if(reset)
		latched_val[23:0] <= #1 24'h000000;
	else if (strobe && (proc_addr[1:0] == 2'b00))
		latched_val[23:0] <= #1 counter[23:0];

always @(posedge sys_clock)
begin
	case(proc_addr[1:0])
		2'b00: encoder_data_out[7:0] <= #1 latched_val[7:0];
		2'b01: encoder_data_out[7:0] <= #1 latched_val[15:8];
		2'b10: encoder_data_out[7:0] <= #1 latched_val[23:16];
		2'b11: encoder_data_out[7:0] <= #1 8'h00;
	endcase
end


always @(posedge sys_clock or posedge reset)
begin
	if(reset)
	begin
		enc_state <= #1 STATE_A;
		counter[23:0] <= #1 24'h000000;
	end 
	else
	begin
		casex (enc_state) //synopsys full_case parallel_case
			CASE_A:
			begin
				if(encoders[1:0] == ENC_B)
				begin
					counter[23:0] <= #1 counter[23:0] + 24'h000001;
					enc_state <= #1 STATE_B;
				end
				if(encoders[1:0] == ENC_D)
				begin
					counter[23:0] <= #1 counter[23:0] - 24'h000001;
					enc_state <= #1 STATE_D;
				end
			end

			CASE_B:
			begin
				if(encoders[1:0] == ENC_C)
				begin
					counter[23:0] <= #1 counter[23:0] + 24'h000001;
					enc_state <= #1 STATE_C;
				end
				if(encoders[1:0] == ENC_A)
				begin
					counter[23:0] <= #1 counter[23:0] - 24'h000001;
					enc_state <= #1 STATE_A;
				end
			end

			CASE_C:
			begin
				if(encoders[1:0] == ENC_D)
				begin
					counter[23:0] <= #1 counter[23:0] + 24'h000001;
					enc_state <= #1 STATE_D;
				end
				if(encoders[1:0] == ENC_B)
				begin
					counter[23:0] <= #1 counter[23:0] - 24'h000001;
					enc_state <= #1 STATE_B;
				end
			end

			CASE_D:
			begin
				if(encoders[1:0] == ENC_A)
				begin
					counter[23:0] <= #1 counter[23:0] + 24'h000001;
					enc_state <= #1 STATE_A;
				end
				if(encoders[1:0] == ENC_C)
				begin
					counter[23:0] <= #1 counter[23:0] - 24'h000001;
					enc_state <= #1 STATE_C;
				end
			end

		endcase
	end
end

endmodule

Click Here To Return: