UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor sunbelt57
Visitor
13,039 Views
Registered: ‎07-08-2015

converting verilog to vhdl

I have a sample project which came with my Waveshare board to decode a 4x4 keypad. The top file is a schematic and there are 2 vhdl files and 1 verilog file. I'm converting the verilog file (key44.v) to my own vhdl (key44.vhd). I have 2 test benches set up for each. Here's the verilog file:

// Module declaration 
module key44
(
	code      ,
	col       ,
	valid     ,
	row       ,
	sys_clk   ,
	rst  
);

//-------------------------------------------------------------------------------------------------
// Port declaration 
output  [3:0]  col     ;
output         valid   ;
output  [3:0]  code    ;

input   [3:0]  row     ;
input          sys_clk,rst ;

//-------------------------------------------------------------------------------------------------
// 
reg     [3:0]  col,code;
reg     [5:0]  state,next_state;

parameter  S_0 = 6'b000001,
           S_1 = 6'b000010,
           S_2 = 6'b000100,
           S_3 = 6'b001000,
           S_4 = 6'b010000,
           S_5 = 6'b100000;
reg        S_row ; 
reg [3:0] count,row_reg,col_reg;
reg       clk2,clk4;
 
 
reg [4:0] Mega_cnt;
wire      clk;

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
// 
always @( posedge sys_clk, negedge rst )
begin
	if(!rst)	Mega_cnt<=0;
	else		Mega_cnt<=Mega_cnt+1;
end

assign clk = Mega_cnt[4];

//-------------------------------------------------------------------------------------------------
// Frequency Division Two 
always @( posedge clk )
clk2 <= ~clk2;

// A quarter of the clk 
always @( posedge clk2 )
clk4 <= ~clk4;

//-------------------------------------------------------------------------------------------------
// Check the Key 
//-------------------------------------------------------------------------------------------------
always @( posedge clk4, negedge rst )
if(!rst)
	begin
		count <= 0;
		S_row <= 0;
	end
else
	begin
		if(!(row[0]&row[1]&row[2]&row[3]))
			begin
				if(count < 'd4)
					count <= count + 1;		// Filter 
				else
					S_row <= 1;
			end
	//	else if(state[5]||state[0])
		else if((state == S_0) || (state == S_5))
			begin
				count <= 0;
				S_row <= 0;
			end
	end

assign valid = ((state == S_1)||(state == S_2)||(state == S_3)||(state == S_4)) &&  (!(row[3]&row[2]&row[1]&row[0]));

//-------------------------------------------------------------------------------------------------
// Save the value of row and col 
always @( negedge clk )
if( valid )
	begin
		row_reg <= row ;
		col_reg <= col ;
	end
/*
else
	begin
		row_reg <= row_reg ;
		col_reg <= col_reg ;
	end*/

//-------------------------------------------------------------------------------------------------
// Decode the Key 
always @( row_reg, col_reg, clk )
	case( {row_reg,col_reg} )
		8'B1110_1110: code = 4'hd;
		8'B1110_1101: code = 4'h9;
		8'B1110_1011: code = 4'h5;
		8'B1110_0111: code = 4'h1;
		
		8'B1101_1110: code = 4'he;
		8'B1101_1101: code = 4'ha;
		8'B1101_1011: code = 4'h6;
		8'B1101_0111: code = 4'h2;
		
		8'B1011_1110: code = 4'hf;
		8'B1011_1101: code = 4'hb;
		8'B1011_1011: code = 4'h7;
		8'B1011_0111: code = 4'h3;
		
		8'B0111_1110: code = 4'h0;
		8'B0111_1101: code = 4'hc;
		8'B0111_1011: code = 4'h8;
		8'B0111_0111: code = 4'h4;
		default		: code = 4'h0;
	endcase
 
//-------------------------------------------------------------------------------------------------
// State Machine : Mealy 
//-------------------------------------------------------------------------------------------------
always @( posedge clk4, negedge rst )
	if( !rst )
		state <= S_0 ;
	else
		state <= next_state ;

//-------------------------------------------------------------------------------------------------
always @( state, row, S_row )
begin
	col = 0;
	//----------------------------------------------
	case( state )
	S_0 :  begin
			col = 4'b0000;
			if(S_row)	next_state = S_1;
			else		next_state = S_0;
		end
	//----------------------------------------------
	// Decoding... 
	S_1 :  begin
			col = 4'b1110;
			if(row!='hf)	next_state = S_5;
			else			next_state = S_2;
		end
	S_2 :  begin
			col = 4'b1101;
			if(row!='hf)	next_state = S_5;
			else			next_state = S_3;
		end 
	S_3 :  begin
			col = 4'b1011;
			if(row!='hf)	next_state = S_5;
			else			next_state = S_4;
		end  
	S_4 :  begin
			col = 4'b0111;
			if(row!='hf)	next_state = S_5;
			else			next_state = S_0;
		end  
	//----------------------------------------------
	S_5 :  begin
			col = 4'b0000;
			if(row == 4'b1111) 	next_state = S_0;
			else 				next_state = S_5;
		end
	default: next_state = S_0;
	endcase
end

endmodule

and here's my vhdl version:

-- key44a.vhd - converted from key44.v (verilog)

library ieee;
USE IEEE.std_logic_1164.ALL;
use ieee.numeric_std.all;

entity key44 is
	port (reset: in std_logic;
		row: in  std_logic_vector(3 downto 0);
		col: out  std_logic_vector(3 downto 0);
		sys_clk: in std_logic;	-- this in NOT the 50MHz clock!
--		valid: out  std_logic;
		code: out std_logic_vector(3 downto 0));
end key44;

architecture key_arch of key44 is
-- signal & constants
	constant DEC: integer:= 5;
	constant MEGA_VAL: integer:= 7;
	
	type state_type is (S_0,S_1,S_2,S_3,S_4,S_5);
	signal state_reg, state_next: state_type;
	signal S_row: std_logic;
	signal count: unsigned(3 downto 0);
	signal row_reg, t_col, col_reg: std_logic_vector(3 downto 0);
	signal clk1, clk2, clk4: std_logic;
	signal Mega_cnt: unsigned(MEGA_VAL-1 downto 0);
	signal t_valid: std_logic;
	signal test: std_logic;
	signal test2: std_logic;
	signal test3: std_logic;
	signal temp: unsigned(7 downto 0);
	signal b_valid: boolean;

begin

	process(reset,sys_clk)
	begin
		if reset = '0' then
			Mega_cnt <= (others=>'0');
			clk1 <= '0';
		elsif sys_clk'event and sys_clk = '1' then
			Mega_cnt <= Mega_cnt + 1;
			clk1 <= Mega_cnt(MEGA_VAL-DEC);
		end if;
	end process;

	process(clk1,reset)
	begin
		if reset = '0' then
			clk2 <= '0';
		elsif clk1'event and clk1 = '1' then
			clk2 <= not clk2;
		end if;
	end process;

	process(clk2,reset)
	begin
		if reset = '0' then
			clk4 <= '0';
		elsif clk2'event and clk2 = '1' then
			clk4 <= not clk4;
		end if;
	end process;
	
--	b_valid := ((state_reg = S_1 or state_reg = S_2 or state_reg = S_2 or state_reg = S_2 or state_reg = S_2) or (not(row(3) and row(2) and row(1) and row(0)))) ;

	process(clk1,reset,state_reg,row)
	begin
		if reset = '0' then
			t_valid <= '0';
		elsif clk1'event and clk1 = '0' then
			if (state_reg = S_1 or state_reg = S_2 or state_reg = S_3 or state_reg = S_4) and
					 (row(0) = '0' or row(1) = '0' or row(2) = '0' or row(3) = '0') then
				t_valid <= '1';
			else
				t_valid <= '0';
				
			end if;
		end if;
	end process;	

	process(clk1,reset,state_reg,row)
	begin
		if reset = '0' then
			test <= '0';
		elsif clk1'event and clk1 = '0' then
			if (state_reg = S_1 or state_reg = S_2 or state_reg = S_3 or state_reg = S_4) then
				test <= '1';
			else
				test <= '0';
				
			end if;
		end if;
	end process;	

	process(clk1,reset,state_reg,row)
	begin
		if reset = '0' then
			test2 <= '0';
		elsif clk1'event and clk1 = '0' then
			if (row(0) = '0' or row(1) = '0' or row(2) = '0' or row(3) = '0') then
				test2 <= '1';
			else
				test2 <= '0';
				
			end if;
		end if;
	end process;	

--	process(state_reg,row)
--	begin
--		if (state_reg = S_1 or state_reg = S_2 or state_reg = S_3 or state_reg = S_4) and
--				 (row(0) = '0' or row(1) = '0' or row(2) = '0' or row(3) = '0') then
--			t_valid <= '1';
--		else
--			t_valid <= '0';
--		end if;
--	end process;	

-- check the key
	process(clk4, reset,row)
	variable temp1: boolean:= FALSE;
	begin
		if reset='0' then
			count <= (others=>'0');
			S_row <= '0';
			test3 <= '0';
			temp1:= FALSE;
		elsif clk4'event and clk4 = '1' then
			temp1 := (row(0) = '0' or row(1) = '0' or row(2) = '0' or row(3) = '0');
			if temp1 = TRUE then
				test3 <= '1';
				if count < 4 then
					count <= count + 1;	
				else
					S_row <= '1';
				end if;
			elsif (state_reg = S_0 or state_reg = S_5) then
				test3 <= '0';
				count <= (others=>'0');
				S_row <= '0';
--				temp:= FALSE;
			end if;
		end if;
	end process;

-- save the value of row and col
	process(t_valid,row,t_col,reset,clk1)
	begin
		if reset = '0' then
			row_reg <= (others=>'0');
			col_reg <= (others=>'0');
--			t_col <= (others=>'0');
		elsif clk1'event and clk1 = '0' then
			if t_valid = '1' then
				row_reg <= row;
				col_reg <= t_col;
			end if;
		end if;
	end process;

	col <= col_reg;

-- decode the key
	process(row_reg, col_reg, clk1)
	begin
		if clk1'event and clk1 = '1' then
			temp <= unsigned(row_reg & col_reg);
			case temp is
				when "11101110" => code <= "1101";
				when "11101101" => code <= "1001";
				when "11101011" => code <= "0101";
				when "11100111" => code <= "0001";

				when "11011110" => code <= "1110";
				when "11011101" => code <= "1010";
				when "11011011" => code <= "0110";
				when "11010111" => code <= "0010";
		
				when "10111110" => code <= "1111";
				when "10111101" => code <= "1011";
				when "10111011" => code <= "0111";
				when "10110111" => code <= "0011";

				when "01111110" => code <= "0000";
				when "01111101" => code <= "1100";
				when "01111011" => code <= "1000";
				when "01110111" => code <= "0100";
				when others => code <= "0000";
			end case;
		end if;
	end process;


-- state machine : Mealy
-- make this a one-process FSM to avoid t_col causing mult input error
--	process(reset,clk4, state_reg, state_next)
--	begin
--		if reset = '0' then
--			state_reg <= S_0;
--			t_col <= (others=>'0');
--		elsif clk4'event and clk4 = '1' then
--			state_reg <= state_next;
--		end if;
--	end process;

-- state machine : Mealy
	process(clk4, reset, state_reg,S_row,t_col,row)
	begin
		if reset = '0' then
			state_reg <= S_0;
			state_next <= S_0;
		elsif clk4'event and clk4 = '1' then
			case state_reg is
				when S_0 =>
					t_col <= "0000";
					if S_row = '1' then
						state_next <= S_1;
					else
						state_next <= S_0;
					end if;
				when S_1 =>
					t_col <= "1110";
					if row /= "1111" then
						state_next <= S_5;
					else
						state_next <= S_2;
					end if;
				when S_2 =>
					t_col <= "1101";
					if row /= "1111" then
						state_next <= S_5;
					else
						state_next <= S_3;
					end if;
				when S_3 =>
					t_col <= "1011";
					if row /= "1111" then
						state_next <= S_5;
					else
						state_next <= S_4;
					end if;
				when S_4 =>
					t_col <= "0111";
					if row /= "1111" then
						state_next <= S_5;
					else
						state_next <= S_0;
					end if;
				when S_5 =>
					t_col <= "0000";
					if row /= "1111" then
						state_next <= S_5;
					else
						state_next <= S_0;
					end if;
				when others =>
					state_next <= S_0;
			end case;
			state_reg <= state_next;
		end if;
	end process;

end key_arch;


The testbench for the verilog is attached as keypad_verilog and the one for vhdl is keypad_vhdl.

The part I'm stumped on is why does S_row start earlier in the vhdl version. Also, I'm not getting a valid signal.

The valid signal in the verilog version is:

assign valid = ((state == S_1)||(state == S_2)||(state == S_3)||(state == S_4)) &&  (!(row[3]&row[2]&row[1]&row[0]));

The only equivalent I could come up with for vhdl is:

	process(clk1,reset,state_reg,row)
	begin
		if reset = '0' then
			t_valid <= '0';
		elsif clk1'event and clk1 = '0' then
			if (state_reg = S_1 or state_reg = S_2 or state_reg = S_3 or state_reg = S_4) and
					 (row(0) = '0' or row(1) = '0' or row(2) = '0' or row(3) = '0') then
				t_valid <= '1';
			else
				t_valid <= '0';
				
			end if;
		end if;
	end process;	

I know this is a lot to ask but I thought someone could suggest something or see something I'm missing. I have the whole project setup at: github

 

 

keypad_vhdl.png
0 Kudos
8 Replies
Visitor sunbelt57
Visitor
13,038 Views
Registered: ‎07-08-2015

Re: converting verilog to vhdl

The previous jpg was the simulation for the vhdl. Here's the one for the verilog:

 

keypad_verilog.JPG
0 Kudos
Visitor sunbelt57
Visitor
13,034 Views
Registered: ‎07-08-2015

Re: converting verilog to vhdl

The incoming clock (clk1) comes from a freq divider. clk2 is clk1/2 and clk4 is clk2/2. The test bench for each stimulates in row(3:0) like this:

row_proc: process
	begin
		row <= "1111";
		wait for 199 us;
		for i in 0 to 20 loop
			row <= "1110"; wait for 1 ms;
			row <= "1111"; wait for 3 ms;
			row <= "1101"; wait for 1 ms;
			row <= "1111"; wait for 3 ms;
			row <= "1011"; wait for 1 ms;
			row <= "1111"; wait for 3 ms;
			row <= "0111"; wait for 1 ms;
			row <= "1111"; wait for 3 ms;
		end loop;	
	end process;	
Tags (3)
0 Kudos
Visitor sunbelt57
Visitor
13,023 Views
Registered: ‎07-08-2015

Re: converting verilog to vhdl

Another thing I'm puzzled about is why the next_state in key44.v go from 1,2,32,4,8,16,1 while the state goes from 1,2,4,8,16,1.

 

I converted the state machine to a one-process because of t_col multiple inputs.

 

And I hade to col in the FSM with t_col because it wouldn't let me read from an output in the process that sets the row_reg and col_reg. Evidently, you can do that with verilog.

0 Kudos
Visitor sunbelt57
Visitor
13,021 Views
Registered: ‎07-08-2015

Re: converting verilog to vhdl

[edit:] And I had to replace col in the FSM with t_col...
0 Kudos
Visitor sunbelt57
Visitor
13,017 Views
Registered: ‎07-08-2015

Re: converting verilog to vhdl

I made a change to the test bench: I added more time for the rows to be non-FF
0 Kudos
Visitor sunbelt57
Visitor
13,003 Views
Registered: ‎07-08-2015

Re: converting verilog to vhdl

I think what I'm not seeing is that the hardware will only return on non-FF row when the col scan matches up with the row from the keypad. I just can't stimulate it with a shifting of column values. I'll have to hook up a keypad and try it out.
0 Kudos
Explorer
Explorer
113 Views
Registered: ‎01-13-2018

Re: converting verilog to vhdl

Hi, 

Is there any tool which convert Verilog code to VHDL ? 

0 Kudos
Adventurer
Adventurer
110 Views
Registered: ‎01-19-2018

Re: converting verilog to vhdl

@sunbelt57,

What is the problem? You have mentioned everything and not the problem.

VHDL and Verilog compilers are there to test your code! Write a good testbench and test them.

 

0 Kudos