MemTest VHDL to Verilog conversion example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--********************************************************************** | |
-- Copyright (c) 1997-2014 by XESS Corp <http://www.xess.com>. | |
-- All rights reserved. | |
-- | |
-- This library is free software; you can redistribute it and/or | |
-- modify it under the terms of the GNU Lesser General Public | |
-- License as published by the Free Software Foundation; either | |
-- version 3.0 of the License, or (at your option) any later version. | |
-- | |
-- This library is distributed in the hope that it will be useful, | |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
-- Lesser General Public License for more details. | |
-- | |
-- You should have received a copy of the GNU Lesser General Public | |
-- License along with this library. If not, see | |
-- <http://www.gnu.org/licenses/>. | |
--********************************************************************** | |
-------------------------------------------------------------------- | |
-- Memory-testing routine | |
-------------------------------------------------------------------- | |
library IEEE; | |
use IEEE.STD_LOGIC_1164.all; | |
--package MemTestPckg is | |
-- | |
-- component MemTest is | |
-- generic( | |
-- PIPE_EN_G : boolean := false; -- enable pipelined operations | |
-- DATA_WIDTH_G : natural := 16; -- memory data width | |
-- ADDR_WIDTH_G : natural := 23; -- memory address width | |
-- BEG_TEST_G : natural := 16#00_0000#; -- beginning test range address | |
-- END_TEST_G : natural := 16#7F_FFFF# -- ending test range address | |
-- ); | |
-- port( | |
-- clk_i : in std_logic; -- master clock input | |
-- rst_i : in std_logic; -- reset | |
-- doAgain_i : in std_logic; -- re-do memory test | |
-- begun_i : in std_logic; -- memory operation begun_i indicator | |
-- done_i : in std_logic; -- memory operation done_i indicator | |
-- dIn_i : in std_logic_vector(DATA_WIDTH_G-1 downto 0); -- data from memory | |
-- rdPending_i : in std_logic; -- read operations in progress_o indicator | |
-- rd_o : out std_logic; -- memory read control signal | |
-- wr_o : out std_logic; -- memory write control signal | |
-- addr_o : out std_logic_vector(ADDR_WIDTH_G-1 downto 0); -- address to memory | |
-- dOut_o : out std_logic_vector(DATA_WIDTH_G-1 downto 0); -- data to memory | |
-- progress_o : out std_logic_vector(1 downto 0); -- memory test progress_o indicator | |
-- err_o : out std_logic -- memory error flag | |
-- ); | |
-- end component; | |
-- | |
--end package; | |
library IEEE, XESS; | |
use IEEE.std_logic_1164.all; | |
use IEEE.numeric_std.all; | |
use XESS.CommonPckg.all; | |
use XESS.RandPckg.all; | |
entity MemTest is | |
generic( | |
PIPE_EN_G : boolean := false; -- enable pipelined operations | |
DATA_WIDTH_G : natural := 16; -- memory data width | |
ADDR_WIDTH_G : natural := 23 -- memory address width | |
--BEG_TEST_G : natural := 16#00_0000#; -- beginning test range address | |
--END_TEST_G : natural := 16#7F_FFFF# -- ending test range address | |
); | |
port( | |
clk_i : in std_logic; -- master clock input | |
rst_i : in std_logic; -- reset | |
doAgain_i : in std_logic; -- re-do memory test | |
begun_i : in std_logic; -- memory operation begun_i indicator | |
done_i : in std_logic; -- memory operation done_i indicator | |
dIn_i : in std_logic_vector(DATA_WIDTH_G-1 downto 0); -- data from memory | |
rdPending_i : in std_logic; -- read operations in progress_o indicator | |
rd_o : out std_logic; -- memory read control signal | |
wr_o : out std_logic; -- memory write control signal | |
addr_o : out std_logic_vector(ADDR_WIDTH_G-1 downto 0); -- address to memory | |
dOut_o : out std_logic_vector(DATA_WIDTH_G-1 downto 0); -- data to memory | |
progress_o : out std_logic_vector(1 downto 0); -- memory test progress_o indicator | |
err_o : out std_logic -- memory error flag | |
); | |
end entity; | |
architecture arch of MemTest is | |
-- states of the memory tester state machine | |
type testState is ( | |
INIT, -- init | |
LOAD, -- load memory with pseudo-random data | |
COMPARE, -- compare memory contents with pseudo-random data | |
EMPTY_PIPE, -- empty read pipeline | |
STOP -- stop and indicate memory status | |
); | |
signal state_r, state_x : testState := INIT; -- state register and next state | |
-- registers | |
signal addr_r, addr_x : unsigned(addr_o'range); -- address register | |
signal err_r, err_x : std_logic := NO; -- error flag | |
-- internal signals | |
signal ld : std_logic; -- load random number gen with seed value | |
signal cke : std_logic; -- clock-enable for random number gen | |
signal rand, rand1 : std_logic_vector(dOut_o'range); -- random number from generator | |
signal seed : std_logic_vector(dIn_i'range); -- random number starting seed | |
begin | |
seed <= (others => '1'); -- random number seed is 111...111 | |
-- random number generator module | |
u0 : randGen | |
port map( | |
clk_i => clk_i, -- input clock | |
cke_i => cke, -- clock-enable to control when new random num is computed | |
ld_i => ld, -- load seed control signal | |
seed_i => seed, -- random number seed | |
rand_o => rand1 -- random number output from generator | |
); | |
rand <= rand1; | |
-- rand <= (others=>'0'); | |
-- rand <= std_logic_vector(addr_r(15 downto 0)); | |
-- rand <= std_logic_vector(TO_UNSIGNED(17,16)); | |
-- connect internal registers to external busses | |
-- memory address bus driven by memory address register | |
addr_o <= std_logic_vector(addr_r); -- linear memory addressing | |
-- addr_o <= std_logic_vector(addr_r(1 downto 0) & addr_r(addr_o'high downto 2)); -- linear addressing simultaneously through each bank | |
dOut_o <= rand; -- always output the current random number to the memory | |
err_o <= err_r; -- output the current memory error status | |
-- memory test controller state machine operations | |
combinatorial : process(state_r, err_r, addr_r, dIn_i, rand, begun_i, done_i, rdPending_i, doAgain_i) | |
begin | |
-- default operations (do nothing unless explicitly stated in the following case statement) | |
rd_o <= NO; -- no memory write | |
wr_o <= NO; -- no memory read | |
ld <= NO; -- don't load the random number generator | |
cke <= NO; -- don't generate a new random number | |
addr_x <= addr_r; -- next address is the same as current address | |
err_x <= err_r; -- error flag is unchanged | |
state_x <= state_r; -- no change in memory tester state | |
-- **** compute the next state and operations **** | |
case state_r is | |
------------------------------------------------------ | |
-- initialize the memory test controller | |
------------------------------------------------------ | |
when INIT => | |
ld <= YES; -- load random number seed | |
cke <= YES; -- enable clocking of rand num gen so seed gets loaded | |
-- @todo: attributes don't convert | |
--addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- load starting mem address | |
addr_x <= to_unsigned(BEG_TEST_G, 23); | |
err_x <= NO; -- clear memory error flag | |
state_x <= LOAD; -- next go to LOAD state and write pattern to memory | |
progress_o <= "00"; -- indicate the current controller state | |
when LOAD => -- load the memory with data from the random number generator | |
progress_o <= "01"; -- indicate the current controller state | |
if PIPE_EN_G = 1 then | |
wr_o <= YES; | |
if begun_i = YES then | |
if addr_r /= END_TEST_G then | |
addr_x <= addr_r + 1; -- so increment address | |
cke <= YES; -- and enable generator clock to get new random num | |
else | |
cke <= YES; -- enable generator clock and | |
ld <= YES; -- reload the generator with the seed value | |
-- @todo: attributes not supported | |
--addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- reset to start of test range | |
addr_x <= TO_UNSIGNED(BEG_TEST_G, 23); -- reset to start of test range | |
state_x <= COMPARE; | |
end if; | |
end if; | |
else | |
if done_i = NO then | |
wr_o <= YES; | |
elsif addr_r /= END_TEST_G then | |
addr_x <= addr_r + 1; -- so increment address | |
cke <= YES; -- and enable generator clock to get new random num | |
else | |
cke <= YES; -- enable generator clock and | |
ld <= YES; -- reload the generator with the seed value | |
--addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- reset to start of test range | |
addr_x <= TO_UNSIGNED(BEG_TEST_G, 23); -- reset to start of test range | |
state_x <= COMPARE; | |
end if; | |
end if; | |
when COMPARE => -- re-run the generator and compare it to memory contents | |
progress_o <= "10"; -- indicate the current controller state | |
if PIPE_EN_G = 1 then | |
rd_o <= YES; | |
if begun_i = YES then | |
addr_x <= addr_r + 1; -- increment address to check next memory location | |
end if; | |
if addr_r = END_TEST_G then | |
state_x <= EMPTY_PIPE; | |
end if; | |
if done_i = YES then | |
if dIn_i /= rand then -- compare value from memory to random number | |
err_x <= YES; -- error if they don't match | |
end if; | |
cke <= YES; -- enable generator clock to get next random num | |
end if; | |
else | |
if done_i = NO then -- current read operation is not complete | |
rd_o <= YES; -- keep read signal active since memory read is not done_i | |
else -- current read operation is complete | |
if dIn_i /= rand then -- compare value from memory to random number | |
err_x <= YES; -- error if they don't match | |
end if; | |
if addr_r = END_TEST_G then | |
state_x <= STOP; -- go to STOP state once entire range has been checked | |
else | |
addr_x <= addr_r + 1; -- increment address to check next memory location | |
end if; | |
cke <= YES; -- and enable generator clock to get next random num | |
end if; | |
end if; | |
when EMPTY_PIPE => | |
progress_o <= "10"; -- indicate the current controller state | |
if done_i = YES then | |
if dIn_i /= rand then -- compare value from memory to random number | |
err_x <= YES; -- error if they don't match | |
end if; | |
cke <= YES; -- enable generator clock to get next random num | |
end if; | |
if rdPending_i = NO then | |
state_x <= STOP; | |
--addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- load starting mem address | |
addr_x <= TO_UNSIGNED(BEG_TEST_G, 23); -- load starting mem address | |
end if; | |
when others => -- memory test is complete | |
progress_o <= "11"; -- indicate the current controller state | |
if doAgain_i = YES then | |
ld <= YES; -- load random number seed | |
cke <= YES; -- enable clocking of rand num gen so seed gets loaded | |
--addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- load starting mem address | |
addr_x <= TO_UNSIGNED(BEG_TEST_G, 23); -- load starting mem address | |
err_x <= NO; -- clear memory error flag | |
state_x <= INIT; -- go to the INIT state and and re-do memory test | |
end if; | |
end case; | |
end process; | |
-- update the registers of the memory tester controller | |
update : process(rst_i, clk_i) | |
begin | |
if rst_i = YES then | |
-- go to starting state and clear error flag when reset occurs | |
state_r <= INIT; | |
elsif rising_edge(clk_i) then | |
-- update error flag, address register, and state | |
err_r <= err_x; | |
addr_r <= addr_x; | |
state_r <= state_x; | |
end if; | |
end process; | |
end architecture; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// File MemTest.vhd translated with vhd2vl v2.4 VHDL to Verilog RTL translator | |
// vhd2vl settings: | |
// * Verilog Module Declaration Style: 2001 | |
// vhd2vl is Free (libre) Software: | |
// Copyright (C) 2001 Vincenzo Liguori - Ocean Logic Pty Ltd | |
// http://www.ocean-logic.com | |
// Modifications Copyright (C) 2006 Mark Gonzales - PMC Sierra Inc | |
// Modifications (C) 2010 Shankar Giri | |
// Modifications Copyright (C) 2002, 2005, 2008-2010 Larry Doolittle - LBNL | |
// http://doolittle.icarus.com/~larry/vhd2vl/ | |
// | |
// vhd2vl comes with ABSOLUTELY NO WARRANTY. Always check the resulting | |
// Verilog for correctness, ideally with a formal verification tool. | |
// | |
// You are welcome to redistribute vhd2vl under certain conditions. | |
// See the license (GPLv2) file included with the source for details. | |
// The result of translation follows. Its copyright status should be | |
// considered unchanged from the original VHDL. | |
//********************************************************************** | |
// Copyright (c) 1997-2014 by XESS Corp <http://www.xess.com>. | |
// All rights reserved. | |
// | |
// This library is free software; you can redistribute it and/or | |
// modify it under the terms of the GNU Lesser General Public | |
// License as published by the Free Software Foundation; either | |
// version 3.0 of the License, or (at your option) any later version. | |
// | |
// This library is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
// Lesser General Public License for more details. | |
// | |
// You should have received a copy of the GNU Lesser General Public | |
// License along with this library. If not, see | |
// <http://www.gnu.org/licenses/>. | |
//********************************************************************** | |
//------------------------------------------------------------------ | |
// Memory-testing routine | |
//------------------------------------------------------------------ | |
//package MemTestPckg is | |
// | |
// component MemTest is | |
// generic( | |
// PIPE_EN_G : boolean := false; -- enable pipelined operations | |
// DATA_WIDTH_G : natural := 16; -- memory data width | |
// ADDR_WIDTH_G : natural := 23; -- memory address width | |
// BEG_TEST_G : natural := 16#00_0000#; -- beginning test range address | |
// END_TEST_G : natural := 16#7F_FFFF# -- ending test range address | |
// ); | |
// port( | |
// clk_i : in std_logic; -- master clock input | |
// rst_i : in std_logic; -- reset | |
// doAgain_i : in std_logic; -- re-do memory test | |
// begun_i : in std_logic; -- memory operation begun_i indicator | |
// done_i : in std_logic; -- memory operation done_i indicator | |
// dIn_i : in std_logic_vector(DATA_WIDTH_G-1 downto 0); -- data from memory | |
// rdPending_i : in std_logic; -- read operations in progress_o indicator | |
// rd_o : out std_logic; -- memory read control signal | |
// wr_o : out std_logic; -- memory write control signal | |
// addr_o : out std_logic_vector(ADDR_WIDTH_G-1 downto 0); -- address to memory | |
// dOut_o : out std_logic_vector(DATA_WIDTH_G-1 downto 0); -- data to memory | |
// progress_o : out std_logic_vector(1 downto 0); -- memory test progress_o indicator | |
// err_o : out std_logic -- memory error flag | |
// ); | |
// end component; | |
// | |
//end package; | |
// no timescale needed | |
module MemTest | |
( | |
input wire clk_i, | |
input wire rst_i, | |
input wire doAgain_i, | |
input wire begun_i, | |
input wire done_i, | |
input wire [DATA_WIDTH_G - 1:0] dIn_i, | |
input wire rdPending_i, | |
output reg rd_o, | |
output reg wr_o, | |
output wire [ADDR_WIDTH_G - 1:0] addr_o, | |
output wire [DATA_WIDTH_G - 1:0] dOut_o, | |
output reg [1:0] progress_o, | |
output wire err_o | |
); | |
parameter PIPE_EN_G=false; | |
parameter [31:0] DATA_WIDTH_G=16; | |
parameter [31:0] ADDR_WIDTH_G=23; | |
parameter BEG_TEST_G = 16'h00_0000; | |
parameter END_TEST_G = 16'h7F_FFFF; | |
// memory address width | |
// master clock input | |
// reset | |
// re-do memory test | |
// memory operation begun_i indicator | |
// memory operation done_i indicator | |
// data from memory | |
// read operations in progress_o indicator | |
// memory read control signal | |
// memory write control signal | |
// address to memory | |
// data to memory | |
// memory test progress_o indicator | |
// memory error flag | |
// states of the memory tester state machine | |
parameter [2:0] | |
INIT = 0, | |
LOAD = 1, | |
COMPARE = 2, | |
EMPTY_PIPE = 3, | |
STOP = 4; | |
reg [2:0] state_r = INIT; reg [2:0] state_x = INIT; // state register and next state | |
// registers | |
reg [ADDR_WIDTH_G - 1:0] addr_r; reg [ADDR_WIDTH_G - 1:0] addr_x; // address register | |
reg err_r = NO; reg err_x = NO; // error flag | |
// internal signals | |
reg ld; // load random number gen with seed value | |
reg cke; // clock-enable for random number gen | |
wire [DATA_WIDTH_G - 1:0] rand; wire [DATA_WIDTH_G - 1:0] rand1; // random number from generator | |
wire [DATA_WIDTH_G - 1:0] seed; // random number starting seed | |
assign seed = {(((DATA_WIDTH_G - 1))-((0))+1){1'b1}}; | |
// random number seed is 111...111 | |
// random number generator module | |
randGen u0( | |
.clk_i(clk_i), | |
// input clock | |
.cke_i(cke), | |
// clock-enable to control when new random num is computed | |
.ld_i(ld), | |
// load seed control signal | |
.seed_i(seed), | |
// random number seed | |
.rand_o(rand1)); | |
assign rand = rand1; | |
// rand <= (others=>'0'); | |
// rand <= std_logic_vector(addr_r(15 downto 0)); | |
// rand <= std_logic_vector(TO_UNSIGNED(17,16)); | |
// connect internal registers to external busses | |
// memory address bus driven by memory address register | |
assign addr_o = (addr_r); | |
// linear memory addressing | |
// addr_o <= std_logic_vector(addr_r(1 downto 0) & addr_r(addr_o'high downto 2)); -- linear addressing simultaneously through each bank | |
assign dOut_o = rand; | |
// always output the current random number to the memory | |
assign err_o = err_r; | |
// output the current memory error status | |
// memory test controller state machine operations | |
always @(state_r or err_r or addr_r or dIn_i or rand or begun_i or done_i or rdPending_i or doAgain_i) begin | |
// default operations (do nothing unless explicitly stated in the following case statement) | |
rd_o <= NO; | |
// no memory write | |
wr_o <= NO; | |
// no memory read | |
ld <= NO; | |
// don't load the random number generator | |
cke <= NO; | |
// don't generate a new random number | |
addr_x <= addr_r; | |
// next address is the same as current address | |
err_x <= err_r; | |
// error flag is unchanged | |
state_x <= state_r; | |
// no change in memory tester state | |
// **** compute the next state and operations **** | |
case(state_r) | |
//---------------------------------------------------- | |
// initialize the memory test controller | |
//---------------------------------------------------- | |
INIT : begin | |
ld <= YES; | |
// load random number seed | |
cke <= YES; | |
// enable clocking of rand num gen so seed gets loaded | |
// @todo: attributes don't convert | |
//addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- load starting mem address | |
addr_x <= (BEG_TEST_G); | |
err_x <= NO; | |
// clear memory error flag | |
state_x <= LOAD; | |
// next go to LOAD state and write pattern to memory | |
progress_o <= 2'b 00; | |
// indicate the current controller state | |
end | |
LOAD : begin | |
// load the memory with data from the random number generator | |
progress_o <= 2'b 01; | |
// indicate the current controller state | |
if(PIPE_EN_G == 1) begin | |
wr_o <= YES; | |
if(begun_i == YES) begin | |
if(addr_r != END_TEST_G) begin | |
addr_x <= addr_r + 1; | |
// so increment address | |
cke <= YES; | |
// and enable generator clock to get new random num | |
end | |
else begin | |
cke <= YES; | |
// enable generator clock and | |
ld <= YES; | |
// reload the generator with the seed value | |
// @todo: attributes not supported | |
//addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- reset to start of test range | |
addr_x <= (BEG_TEST_G); | |
// reset to start of test range | |
state_x <= COMPARE; | |
end | |
end | |
end | |
else begin | |
if(done_i == NO) begin | |
wr_o <= YES; | |
end | |
else if(addr_r != END_TEST_G) begin | |
addr_x <= addr_r + 1; | |
// so increment address | |
cke <= YES; | |
// and enable generator clock to get new random num | |
end | |
else begin | |
cke <= YES; | |
// enable generator clock and | |
ld <= YES; | |
// reload the generator with the seed value | |
//addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- reset to start of test range | |
addr_x <= (BEG_TEST_G); | |
// reset to start of test range | |
state_x <= COMPARE; | |
end | |
end | |
end | |
COMPARE : begin | |
// re-run the generator and compare it to memory contents | |
progress_o <= 2'b 10; | |
// indicate the current controller state | |
if(PIPE_EN_G == 1) begin | |
rd_o <= YES; | |
if(begun_i == YES) begin | |
addr_x <= addr_r + 1; | |
// increment address to check next memory location | |
end | |
if(addr_r == END_TEST_G) begin | |
state_x <= EMPTY_PIPE; | |
end | |
if(done_i == YES) begin | |
if(dIn_i != rand) begin | |
// compare value from memory to random number | |
err_x <= YES; | |
// error if they don't match | |
end | |
cke <= YES; | |
// enable generator clock to get next random num | |
end | |
end | |
else begin | |
if(done_i == NO) begin | |
// current read operation is not complete | |
rd_o <= YES; | |
// keep read signal active since memory read is not done_i | |
end | |
else begin | |
// current read operation is complete | |
if(dIn_i != rand) begin | |
// compare value from memory to random number | |
err_x <= YES; | |
// error if they don't match | |
end | |
if(addr_r == END_TEST_G) begin | |
state_x <= STOP; | |
// go to STOP state once entire range has been checked | |
end | |
else begin | |
addr_x <= addr_r + 1; | |
// increment address to check next memory location | |
end | |
cke <= YES; | |
// and enable generator clock to get next random num | |
end | |
end | |
end | |
EMPTY_PIPE : begin | |
progress_o <= 2'b 10; | |
// indicate the current controller state | |
if(done_i == YES) begin | |
if(dIn_i != rand) begin | |
// compare value from memory to random number | |
err_x <= YES; | |
// error if they don't match | |
end | |
cke <= YES; | |
// enable generator clock to get next random num | |
end | |
if(rdPending_i == NO) begin | |
state_x <= STOP; | |
//addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- load starting mem address | |
addr_x <= (BEG_TEST_G); | |
// load starting mem address | |
end | |
end | |
default : begin | |
// memory test is complete | |
progress_o <= 2'b 11; | |
// indicate the current controller state | |
if(doAgain_i == YES) begin | |
ld <= YES; | |
// load random number seed | |
cke <= YES; | |
// enable clocking of rand num gen so seed gets loaded | |
//addr_x <= TO_UNSIGNED(BEG_TEST_G, addr_x'length); -- load starting mem address | |
addr_x <= (BEG_TEST_G); | |
// load starting mem address | |
err_x <= NO; | |
// clear memory error flag | |
state_x <= INIT; | |
// go to the INIT state and and re-do memory test | |
end | |
end | |
endcase | |
end | |
// update the registers of the memory tester controller | |
always @(posedge rst_i or posedge clk_i) begin | |
if(rst_i == YES) begin | |
// go to starting state and clear error flag when reset occurs | |
state_r <= INIT; | |
end else begin | |
// update error flag, address register, and state | |
err_r <= err_x; | |
addr_r <= addr_x; | |
state_r <= state_x; | |
end | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment