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
|