Reputation: 49
I'm trying to convert some code from Verilog to VHDL for project need. The original code is in Verilog, the aim of the code is to realizing MIG DDR2/3 write and read, partly shown as following:
module ddr3_rw #
(
parameter integer WR_LEN = 1024 ,
parameter integer DATA_WIDTH = 128 ,
parameter integer ADDR_WIDTH = 28
)(
input ui_clk ,
input ui_clk_sync_rst ,
input init_calib_complete ,
input app_rdy ,
input app_wdf_rdy ,
input app_rd_data_valid ,
input [DATA_WIDTH - 1:0] app_rd_data ,
output reg [ADDR_WIDTH - 1:0] app_addr ,
output app_en ,
output app_wdf_wren ,
output app_wdf_end ,
output [2:0] app_cmd ,
output reg [DATA_WIDTH - 1:0] app_wdf_data ,
output reg error_flag
);
localparam IDLE = 4'b0001 ;
localparam WRITE = 4'b0010 ;
localparam WAIT = 4'b0100 ;
localparam READ = 4'b1000 ;
//reg define ----------------------------------------
reg [3:0] cur_state ;
reg [3:0] next_state ;
reg [ADDR_WIDTH - 1:0] rd_addr_cnt ;
reg [ADDR_WIDTH - 1:0] wr_addr_cnt ;
reg [ADDR_WIDTH - 1:0] rd_cnt ;
//wire define ---------------------------------------
wire error ;
wire rst_n ;
wire wr_proc ;
wire wr_last ;
wire rd_addr_last ;
assign rst_n = ~ui_clk_sync_rst;
assign app_en = app_rdy && ((cur_state == WRITE && app_wdf_rdy) || cur_state == READ);
assign app_wdf_wren = (cur_state == WRITE) && wr_proc;
assign app_wdf_end = app_wdf_wren;
assign app_cmd = (cur_state == READ) ? 3'd1 :3'd0;
assign wr_proc = ~app_cmd && app_rdy && app_wdf_rdy;
assign wr_last = app_wdf_wren && (wr_addr_cnt == WR_LEN - 1) ;
assign rd_addr_last = (rd_addr_cnt == WR_LEN - 1) && app_rdy && app_cmd;
and here is how I convert:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.std_logic_unsigned;
use IEEE.std_logic_misc;
use IEEE.NUMERIC_STD.ALL;
entity ddr2_rw is
generic (
WR_LEN: integer := 1024;
DATA_WIDTH: integer := 128;
ADDR_WIDTH: integer := 28);
port (
ui_clk: in std_logic;
ui_clk_sync_rst: in std_logic;
init_calib_complate: in std_logic;
app_rdy: in std_logic;
app_wdf_rdy: in std_logic;
app_rd_data_valid: in std_logic;
app_rd_data: out std_logic_vector(DATA_WIDTH-1 downto 0);
app_addr: out std_logic_vector(ADDR_WIDTH-1 downto 0);
app_en: out std_logic;
app_wdf_wren: out std_logic;
app_wdf_end: out std_logic;
app_cmd: out std_logic_vector(2 downto 0);
app_wdf_data: out std_logic_vector(DATA_WIDTH-1 downto 0));
end ddr2_rw;
architecture ddr2_rw_arch of ddr2_rw is
constant IDLE: std_logic_vector(3 downto 0) := "0001";
constant WRITE: std_logic_vector(3 downto 0) := "0010";
constant WAITTING: std_logic_vector(3 downto 0) := "0100";
constant READ: std_logic_vector(3 downto 0) := "1000";
type state is( IDLE, WRITE, WATTING, READ);
signal cur_state, next_state: state;
signal rd_addr_cnt: std_logic_vector(ADDR_WIDTH-1 downto 0);
signal wr_addr_cnt: std_logic_vector(ADDR_WIDTH-1 downto 0);
signal rd_cnt: std_logic_vector(ADDR_WIDTH-1 downto 0);
signal rst_n: std_logic;
signal error: std_logic;
signal wr_proc: std_logic;
signal wr_last: std_logic;
signal rd_addr_last:std_logic;
begin
rst_n <= not ui_clk_sync_rst;
wr_last <= app_wdf_wren and (conv_integer(wr_addr_cnt) = WR_LEN-1);
process begin
case cur_state is
when WRITE => app_en <= app_rdy and app_wdf_rdy;
app_wdf_wren <= wr_proc;
app_wdf_end <= app_wdf_wren;
app_cmd <= "000";
when READ => app_en <= app_rdy;
app_cmd <= "001";
wr_proc <= app_rdy and app_wdf_rdy;
when others => app_en <= '0';
app_cmd <= "000";
end case;
end process;
end ddr2_rw_arch;
before that, I tried to convert assign app_en = app_rdy && ((cur_state == WRITE && app_wdf_rdy) || cur_state == READ);
to app_en <= app_rdy and ((cur_state = WRITE and app_wdf_rdy) or cur_state = READ);
in VHDL, but Vivado report "No suitable operator definition found for '='", so I changed this-alike code to case-clause block, as shown above. However there still have two errors in the clause wr_last <= app_wdf_wren and (conv_integer(wr_addr_cnt) = WR_LEN-1);
, one is conv_integer
function, Vivado report "No matching subprogram was found"; the other is still at =
:"No suitable operator definition found for '='".
Now I have two question:
std_logic_vector
in VHDL, and return if it is identical?Thank you for your time to answer these questions!
Upvotes: 1
Views: 870
Reputation: 56
The problem you are having is the function conv_integer() does not accept a std_logic_vector as an argument. These are the 4 supported datatypes.
You should do a double conversion for that. For more information on that I suggest reading on numeric_std, the official IEEE package, which you already include.
Regarding your second error, I am not entirely sure, but I think the problem is you are using the equality operator in a signal assignment. This operator returns a boolean, which is not assignable to a std_logic signal and therefore cannot be used in the same line (Vivado thinks it must be another operator then).
To try and fix both errors, as well as adding clarity to your code, I would change some lines to the following:
signal wr_addr_cnt_is_wr_length : std_logic;
begin
rst_n <= not ui_clk_sync_rst;
wr_addr_cnt_is_wr_length <= '1' when (to_integer(unsigned(wr_addr_cnt)) = (WR_LEN-1)) else '0';
wr_last <= app_wdf_wren and wr_addr_cnt_is_wr_length;
Upvotes: 2