I want to write verilog code of Dual port ROM in order to access two addresses simultaneously. I write the verilog code for Single port ROM but can't able to et it for Dual port ROM.
This is my verilog code for sinle port ROM.
always #(posedge clk)
begin
case(addr)
3'b000:
begin
dout0<=9'b001001001;
mod70<=001;
mod50<=001;
mod30<=001;
end
3'b001:
begin
dout1<=9'b010010010;
mod71<=010;
mod51<=001;
mod31<=010;
end
3'b010:
begin
dout2<=9'b100100001;
mod72<=100;
mod52<=100;
mod32<=001;
end
3'b011:
begin
dout3<=9'b001011010;
mod73<=001;
mod53<=011;
mod33<=010;
end
3'b100:
begin
dout4<=9'b010001001;
mod74<=010;
mod54<=001;
mod34<=001;
end
3'b101:
begin
dout5<=9'b100010010;
mod75<=100;
mod55<=010;
mod35<=010;
end
3'b110:
begin
dout6<=9'b001100001;
mod76<=001;
mod56<=100;
mod36<=001;
end
3'b111:
begin
dout7<=9'b010011010;
mod77<=010;
mod57<=011;
mod37<=010;
end
endcase
end
On page 147 of the Xilinx XST user guide you will find examples of RAM and ROM.
They do not provide a dual-port ROM example, but they provide dual-port RAM, and you can omit the write to make it a ROM:
This example is on page 164:
module v_rams_11 (clk, a, dpra, spo, dpo);
input clk;
input we;
input [5:0] a;
input [5:0] dpra;
output [15:0] spo;
output [15:0] dpo;
reg [15:0] ram [63:0];
reg [5:0] read_a;
reg [5:0] read_dpra;
always #(posedge clk) begin
read_a <= a;
read_dpra <= dpra;
end
assign spo = ram[read_a];
assign dpo = ram[read_dpra];
endmodule
Related
Wanted to check with you experts if there are any drawbacks in this funtion. Will it work properly on the various Windows OS ? I am using Delphi Seattle (32 and 64 bit exe's). I am using this instead of Findfirst for its speed.
function GetFileDetailsFromAttr(pFileName:WideString):int64;
var
wfad: TWin32FileAttributeData;
wSize:LARGE_INTEGER ;
begin
Result:=0 ;
if not GetFileAttributesEx(pwidechar(pFileName), GetFileExInfoStandard,#wfad) then
exit;
wSize.HighPart:=wfad.nFileSizeHigh ;
wSize.LowPart:=wfad.nFileSizeLow ;
result:=wsize.QuadPart ;
end;
The typical googled samples shown with this command does not work for filesize > 9GB
function GetFileAttributesEx():Int64 using
begin
...
result:=((&wfad.nFileSizeHigh) or (&wfad.nFileSizeLow))
Code with variant record is correct.
But this code
result:=((&wfad.nFileSizeHigh) or (&wfad.nFileSizeLow))
is just wrong, result cannot overcome 32-bit border
Code from link in comment
result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
is wrong because it does not account how compiler works with 32 and 64-bit values. Look at the next example showing how to treat this situation properly (for value d, e):
var
a, b: DWord;
c, d, e: Int64;
wSize:LARGE_INTEGER ;
begin
a := 1;
b := 1;
c := Int64(a) or Int64(b shl 32);
d := Int64(a) or Int64(b) shl 32;
wSize.LowPart := a;
wSize.HighPart := b;
e := wsize.QuadPart;
Caption := Format('$%x $%x $%x', [c, d, e]);
Note that in the expression for c 32-bit value is shifted by 32 bits left and looses set bit, then zero transforms to 64-bit.
Unbound to how you get the filesize: it would even be faster if you'd use a type (manual) that exists for ~25 years already to assign the filesize directly to the function's result instead of using an intermediate variable:
Int64Rec(result).Hi:= wfad.nFileSizeHigh;
Int64Rec(result).Lo:= wfad.nFileSizeLow;
end;
In case this isn't obvious to anyone here's what the compilation looks like:
Above: the intermediate variable w: LARGE_INTEGER first gets assigned the two 32bit parts and then is assigned itself to the function's result. Cost: 10 instructions.
Above: the record Int64Rec is used to cast the function's result and assign both 32bit parts directly, without the need of any other variable. Cost: 6 instructions.
Environment used: Delphi 7.0 (Build 8.1), compiler version 15.0, Win32 executable, code optimization: on.
A newbie question related to vhdl attributes. In this implementation of 128-deep 8-bit delay line on LUT RAM, attribute part confuses me.
entity srl_128_lutram is
generic (
LENGTH : integer := 128;
ADDRWIDTH : integer := 7;
WIDTH : integer := 8);
port (
CLK : in std_logic;
SHIFT_IN : in std_logic_vector(WIDTH-1 downto 0);
SHIFT_OUT : out std_logic_vector(WIDTH-1 downto 0));
end srl_128_lutram;
architecture behavioral of srl_128_lutram is
signal CNTR : std_logic_vector(ADDRWIDTH-1 downto 0);
type ram_type is array (0 to LENGTH-2) of std_logic_vector(WIDTH-1 downto 0);
signal RAM : ram_type := (others => (others => ’0’));
attribute ram_style : string;
attribute ram_style of RAM : signal is "distributed";
begin
counter : process (CLK)
begin
if CLK’event and CLK = ’1’ then
if CNTR = conv_std_logic_vector(LENGTH-2, ADDRWIDTH) then
CNTR <= (others => ’0’);
else
CNTR <= CNTR + ’1’;
end if;
end if;
end process counter;
memory : process (CLK)
begin
if CLK’event and CLK = ’1’ then
RAM(conv_integer(CNTR)) <= SHIFT_IN;
SHIFT_OUT <= RAM(conv_integer(CNTR));
end if;
end process memory;
end behavioral;
My question is what purpose of attributes are here ? What would happen without these two lines ?
EDIT :
Attributes are used to give some directives to synthetizer.
The attribute syntax is a bit confusing but the meaning of your line is the following : For my signal RAM use the attribute ram_style with the value distributed. The attribute will never be used later in the code, it has already given his informations.
Note : attributes are differents from a synthetizer to another.
OLD :
The attribute RAM_STYLE gives to the synthetizer the type of physical cells use to implement your RAM.
In your case it will choose LUT rams. So it will consume some LUT rams of your total LUT ram ressources in your FPGA. You can also to use block RAM.
If you don't use this attribute, synthetizer will choose by itself between these 2 cells (probably with ressource and performance considerations).
Sources : https://www.xilinx.com/support/documentation/sw_manuals/xilinx2012_3/ug901-vivado-synthesis.pdf (page 36)
My question is how to get hostnames of all ip addresses which are betwwen given ip range. I know the function for getting hostnames from ip address but I just want to know how to get ip addresses from given range
Example:
input is given in two edixboxes in first '0.0.0.0' and in second '1.1.1.1' so I want all ip addresses between this range ...
I tried my best but it is too complex. Is there any function or command to get ip addresses between given range?
function IPAddrToName(IPAddr: string): string;
var
SockAddrIn: TSockAddrIn;
HostEnt: PHostEnt;
WSAData: TWSAData;
begin
WSAStartup($101, WSAData);
SockAddrIn.sin_addr.s_addr := inet_addr(PChar(IPAddr));
HostEnt := GetHostByAddr(#SockAddrIn.sin_addr.S_addr, 4, AF_INET);
if HostEnt<>nil then
begin
Result := StrPas(Hostent^.h_name)
end
else
begin
Result := '';
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := IPAddrToName(Edit1.Text);
end;
Use inet_addr to convert the dotted text form of the IP address into an unsigned 32 bit integer. Do that for both addresses. And then loop from one to the other with a simple for loop.
var
ip, ip1, ip2: Cardinal;
....
ip1 := ntohl(inet_addr(PChar(edit1.Text)));
ip2 := ntohl(inet_addr(PChar(edit2.Text)));
for ip := min(ip1,ip2) to max(ip1,ip2) do
// use ip
I skipped any validation. You would not. Note also that inet_addr returns a value with network byte order. For the loop to work we must switch to host byte order.
This only really makes sense for ranges that span an entire subnet mask. For instance it makes sense to enumerate all addresses between 192.168.1.0 and 192.168.1.255. But it makes no sense at all to ask for all addresses between 1.0.0.0 and 1.1.1.1 as per the example in your question.
So I think you'll need to reconsider and think about iterating over all addresses in a network.
You also ask, in comments, how to convert from numeric form to dotted form. Use inet_ntoa for that.
var
addr: in_addr;
dottedAddr: string;
....
addr.S_addr := htonl(ip);
dottedAddr := inet_ntoa(addr);
Generating IP addresses is not that complicated. Just convert range bounds to 4 byte integers and iterate between bounds. Pay special attention to bytes order so integers was correctly converted to IP addreses.
What is the meaning of the internet connection statuses?
I can't figure out which status represents a router, number 3?
What does 4 mean?
uses
WinInet;
const
MODEM = 1;
LAN = 2;
PROXY = 4;
BUSY = 8;
function GetConnectionKind(var strKind: string): Boolean;
var
flags: DWORD;
begin
strKind := '';
Result := InternetGetConnectedState(#flags, 0);
if Result then
begin
if (flags and MODEM) = MODEM then strKind := 'Modem';
if (flags and LAN) = LAN then strKind := 'LAN';
if (flags and PROXY) = PROXY then strKind := 'Proxy';
if (flags and BUSY) = BUSY then strKind := 'Modem Busy';
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
strKind: string;
begin
if GetConnectionKind(strKind) then
ShowMessage(strKind);
end;
[InternetGetConnectedState](http://msdn.microsoft.com/en-us/library/aa384702(VS.85%29.aspx) returns a bitmask in the first parameter that looks like this:
76543210 <-- bit numbers
|| ||||
|| |||+- INTERNET_CONNECTION_MODEM
|| ||+-- INTERNET_CONNECTION_LAN
|| |+--- INTERNET_CONNECTION_PROXY
|| +---- INTERNET_CONNECTION_MODEM_BUSY (No longer used)
|+------ INTERNET_CONNECTION_OFFLINE
+------- INTERNET_CONNECTION_CONFIGURED
If a given bit is set, the connection is of that type. So if bit nr. 2 is set, you're connected through a proxy.
Additionally, the function returns a TRUE/FALSE value, indicating whether you are connected to the internet.
The values you have in your code, 1, 2, 4, 8, corresponds to the decimal value of those bits, counting from the right.
Basically the code inspects each bit in turn, and sets the strKind variable to a text indicating the nature of the connection.
You're asking "which is router? 3?", and I assume you mean by that "how do I figure out that my connection is through a router?". I would assume this would be the same as the LAN connection, presumably the LAN has a bridge somewhere to access the internet through.
The codes 1, 2, 4, 8 represent bitmasks. I generally prefer to always use bitmasks in hex to avoid any confusion, its fairly easy to remember since the pattern continues in nibbles (the set of 4 binary bits).
HEX BINARY DEC
$01 00000001 1
$02 00000010 2
$04 00000100 4
$08 00001000 8
$10 00010000 16
$20 00100000 32
$40 01000000 64
$80 10000000 128
If you ever want to check two values at once, you can OR them together, for example $01 or $02 = $03 (binary 00000011). So a 3 would be BOTH a modem AND a lan.
A common practice to see if something is set or not, would be to AND it with the mask. for example, if my number is 3, and i "and" this with $02, then the result is $02 since the bit for both the mask AND the value were both set. If my number is 4 and I "and" this with $02, then the result is $00 since the bit for both the mask and the value were not set.
Of course this doesn't answer what I think your real question is. The router would be impossible to determine just by checking only this mask. This mask just tells you if your connected via a modem (aka Dialup) or a network adapter. The router would be beyond the network adapter, and would require further analysis of the network to accurately determine.
The constant values are flags which means two things: (1) you cannot have a "3" value and (2) you can have more than one value in the "flags" result. For example, for result 9 (1001 in binary) the first and last checks would be true.
For more info on the result meaning check the MSDN reference for InternetGetConnectedState.
So I always heard that class fields (heap based) were initialized, but stack based variables were not. I also heard that record members (also being stack based) were also not initialized. The compiler warns that local variables are not initialized ([DCC Warning] W1036 Variable 'x' might not have been initialized), but does not warn for record members. So I decided to run a test.
I always get 0 from Integers and false from Booleans for all record members.
I tried turning various compiler options (debugging, optimizations, etc.) on and off, but there was no difference. All my record members are being initialized.
What am I missing? I am on Delphi 2009 Update 2.
program TestInitialization;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TR = Record
Public
i1, i2, i3, i4, i5: Integer;
a: array[0..10] of Integer;
b1, b2, b3, b4, b5: Boolean;
s: String;
End;
var
r: TR;
x: Integer;
begin
try
WriteLn('Testing record. . . .');
WriteLn('i1 ',R.i1);
WriteLn('i2 ',R.i2);
WriteLn('i3 ',R.i3);
WriteLn('i4 ',R.i4);
WriteLn('i5 ',R.i5);
Writeln('S ',R.s);
Writeln('Booleans: ', R.b1, ' ', R.b2, ' ', R.b3, ' ', R.b4, ' ', R.b5);
Writeln('Array ');
for x := 0 to 10 do
Write(R.a[x], ' ');
WriteLn;
WriteLn('Done . . . .');
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
ReadLn;
end.
Output:
Testing record. . . .
i1 0
i2 0
i3 0
i4 0
i5 0
S
Booleans: FALSE FALSE FALSE FALSE FALSE
Array
0 0 0 0 0 0 0 0 0 0 0
Done . . . .
Global variables are zero-initialized. Variables used in the context of the main begin..end block of a program can be a special case; sometimes they are treated as local variables, particularly for-loop indexers. However, in your example, r is a global variable and allocated from the .bss section of the executable, which the Windows loader ensures is zero-filled.
Local variables are initialized as if they were passed to the Initialize routine. The Initialize routine uses runtime type-info (RTTI) to zero-out fields (recursively - if a field is of an array or record type) and arrays (recursively - if the element type is an array or a record) of a managed type, where a managed type is one of:
AnsiString
UnicodeString
WideString
an interface type (including method references)
dynamic array type
Variant
Allocations from the heap are not necessarily initialized; it depends on what mechanism was used to allocate memory. Allocations as part of instance object data are zero-filled by TObject.InitInstance. Allocations from AllocMem are zero-filled, while GetMem allocations are not zero-filled. Allocations from New are initialized as if they were passed to Initialize.
I always get 0 from Integers and false from Booleans for all record members.
I tried turning various compiler options (debugging, optimizations, etc.) on and off, but there was no difference. All my record members are being initialized.
What am I missing?
Well, apart from your test using global instead of local variables: the important thing that you are missing is the distinction between variables that coincidentally appear to be initialised, and variables that actally are initialised.
BTW: This is the reason programmers who don't check their warnings make the common mistake of assuming their poorly written code is behaving correctly when the few tests they do; happen to have 0 and False defaults.... Want To Buy: random initialisation of local variables for debug builds.
Consider the following variation on your test code:
program LocalVarInit;
{$APPTYPE CONSOLE}
procedure DoTest;
var
I, J, K, L, M, N: Integer;
S: string;
begin
Writeln('Test default values');
Writeln('Numbers: ', I:10, J:10, K:10, L:10, M:10, N:10);
Writeln('S: ', S);
I := I + 1;
J := J + 2;
K := K + 3;
L := L + 5;
M := M + 8;
N := N + 13;
S := 'Hello';
Writeln('Test modified values');
Writeln('Numbers: ', I:10, J:10, K:10, L:10, M:10, N:10);
Writeln('S: ', S);
Writeln('');
Writeln('');
end;
begin
DoTest;
DoTest;
Readln;
end.
With the following sample output:
Test default values
Numbers: 4212344 1638280 4239640 4239632 0 0
S:
Test modified values
Numbers: 4212345 1638282 4239643 4239637 8 13 //Local vars on stack at end of first call to DoTest
S: Hello
Test default values
Numbers: 4212345 1638282 4239643 4239637 8 13 //And the values are still there on the next call
S:
Test modified values
Numbers: 4212346 1638284 4239646 4239642 16 26
S: Hello
Notes
The example works best if you compile with optimisation off. Otherwise, if you have optimisation on:
Some local vars will be manipulated in CPU registers.
And if you view the CPU stack while stepping through the code you'll note for example that I := I + 1 doesn't even modify the stack. So obviously the change cannot be carried through.
You could experiment with different calling conventions to see how that affects things.
You can also test the effect of setting the local vars to zero instead of incrementing them.
This illustrates how you are entirely dependent on what found its way onto the stack before your method was called.
Note that in the example code you provided, the record is actually a global variable, so it will be completely initialized. If you move all that code to a function, it will be a local variable, and so, per the rules given by Barry Kelly, only its string field will be initialized (to '').
I have a similar situation, and thought the same, but when I add other variables used before the record, the values become garbage, so before I use my record I had to initialize using
FillChar(MyRecord, SizeOf(MyRecord), #0)