I'm trying to create a 4*4 matrix in this form:
2 3 1 1
1 2 3 1
1 1 2 3
3 1 1 2
Then I need to assign the values element in each location to multiply by 4 inputs each one 8 bits.
a0, a1, a2, a3
I have tried to write this code :
module Mix_Nibbles_Matriex(
out_0,out_1,out_2,out_3,nibble_0,nibble_1,nibble_2,nibble_3,
clk,rst,load
);
input clk,rst,load ;
output reg [7:0] out_0,out_1,out_2,out_3;
input [7:0] nibble_0,nibble_1,nibble_2,nibble_3;
//wire matrix[3:0][0:3];
reg [1:0][7:0] a_unpacked_array[4];
always #( posedge clk or negedge rst)
if (!rst)
a_unpacked_array[0][0]=0;
else if (load)
assign a_unpacked_array[0][0]=2;
assign a_unpacked_array[0][1]=3;
assign a_unpacked_array[0][2]=1;
assign a_unpacked_array[0][3]=1;
assign a_unpacked_array[1][0]=2;
assign a_unpacked_array[1][1]=3;
assign a_unpacked_array[1][2]=1;
assign a_unpacked_array[1][3]=1;
assign a_unpacked_array[2][0]=2;
assign a_unpacked_array[2][1]=3;
assign a_unpacked_array[2][2]=1;
assign a_unpacked_array[2][3]=1;
assign a_unpacked_array[3][0]=2;
assign a_unpacked_array[3][1]=3;
assign a_unpacked_array[3][2]=1;
assign a_unpacked_array[3][3]=1;
//display ("a_unpacked_array = %b", a_unpacked_array);
endmodule
I'm still have these errors:
ERROR:HDLCompiler:939 - "D:/Embedded_Project/Mix_Nibbles_Matriex.v" Line 38: Single value range is not allowed in this mode of verilog
ERROR:HDLCompiler:1439 - "D:/Embedded_Project/Mix_Nibbles_Matriex.v" Line 38: Multiple packed dimensions are not allowed in this mode of verilog
ERROR:HDLCompiler:1417 - "D:/Embedded_Project/Mix_Nibbles_Matriex.v" Line 44: Bit-select or part-select is not allowed in a assign statement for non-net a_unpacked_array
ERROR:HDLCompiler:598 - "D:/Embedded_Project/Mix_Nibbles_Matriex.v" Line 27: Module ignored due to previous errors.
There are couple problems with your code.
Verilog doesn't support multiple packed dimensions. You'd need to use SystemVerilog to make this construct work. You can also follow #Greg suggestion to use unpacked dimension.
reg [1:0][7:0] a_unpacked_array[4]; - compiler tries to treat 4 as range, but single value range are not allowed. Maybe what you meant is [3:0]? Also [1:0] should be probably [3:0].
Your always block has some issues: missing begin-end, unnecessary assign keywords, etc.:
always #(posedge clk or negedge rst)
if (!rst) begin
a_unpacked_array[0][0] <= 0;
//...
end else if (load) begin
a_unpacked_array[0][0] <= 2;
//...
end
Related
I am writing a VHDL Program for 4:1 MUX and am facing a error on the line where process clause starts
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux_41 is
Port ( inp : in STD_LOGIC_VECTOR (0 downto 3);
outp : out STD_LOGIC;
sel : in STD_LOGIC_VECTOR (1 downto 0));
end mux_41;
architecture Behavioral of mux_41 is
begin
Process(inp[0],inp[1],inp[2],inp[3],sel[0],sel[1])
begin
if(sel = "00")
then outp <= inp[0];
elsif(sel = "01")
then outp <= inp[1];
elsif(sel = "10")
then outp <= inp[2];
else outp <= inp[3];
end if;
end process;
end Behavioral;
Is this the right way to pass sensitivity list to process?
In VHDL when you want to access to a particular element of an array (std_logic_vector are array), you have to use () instead of [].
Process(inp(0),inp(1),inp(2),inp(3),sel(0),sel(1))
begin
if(sel = "00")
then outp <= inp(0);
elsif(sel = "01")
then outp <= inp(1);
elsif(sel = "10")
then outp <= inp(2);
else outp <= inp(3);
end if;
end process;
The OP doesn't show the complete error message.
It appears to be in the sensitivity list for the process where inp is a signal_name and the particular parser doesn't use syntactic predicates:
IEEE Std 1076-2008 10.2 Wait statements
sensitivity_list ::= signal_name { , signal_name }
and here the selected names (8.3) are all static names (8.1) and all the elements of both sel and inp are evaluated in the process if statement (10.8) and should be included in the sensitivity set (10.2).
1.3.2 Syntactic description
The form of a VHDL description is described by means of context-free syntax using a simple variant of the Backus-Naur form (BNF); in particular:
...
g) If the name of any syntactic category starts with an italicized part, it is equivalent to the category name without the italicized part. The italicized part is intended to convey some semantic information. For example, type_name and subtype_name are both syntactically equivalent to name alone
...
It's possible to write a parser that uses a symbol table containing declarations of named entities (which precede the use of a name in a description). It simplifies both syntactical and semantic analysis while allowing the rules of visibility and scope to be tracked.
In any event not using syntactic predicates results in a different error message. Instead of an error describing a signal as not having a signature you get an error message saying the signature is malformed or isn't applicable (there are several rules that might be applicable without the syntactic predicates).
The error actually occurs for the first left square bracket. Selected names uses parentheses (round brackets in parts or Europe) instead of square brackets. Also inp by itself has elements 3 downto 0 or 0 to 3 (noting inp : in STD_LOGIC_VECTOR (0 downto 3) has a null range (5.2.1) and no elements).
5.2.1 pargraphs 3 and 4:
A range specifies a subset of values of a scalar type. A range is said to be a null range if the specified subset is empty.
The range L to R is called an ascending range; if L > R, then the range is a null range. The range L downto R is called a descending range; if L < R, then the range is a null range. ...
With a process sensitivity list a process statement (11.3) is assumed to have a single implicit wait statement as it's last sequential statement. The rule for constructing the sensitivity set for the implicit wait statement in a process statement are found in 10.2 Wait statement, where the implicit wait statement will use the longest static prefix (8.1) of any signal name in the process sensitivity list and would be equivalent to process (sel, inp).
11.3 Process statement paragraph 4:
If a process sensitivity list appears following the reserved word process, then the process statement is assumed to contain an implicit wait statement as the last statement of the process statement part; this implicit wait statement is of the form
wait on sensitivity_list ;
where the sensitivity list is determined in one of two ways. If the process sensitivity list is specified as a sensitivity list, then the sensitivity list of the wait statement is that following the reserved word process. ...
10.2 Wait statement paragraphs 3 and 4:
The sensitivity clause defines the sensitivity set of the wait statement, which is the set of signals to which the wait statement is sensitive. Each signal name in the sensitivity list identifies a given signal as a member of the sensitivity set. Each signal name in the sensitivity list shall be a static signal name, and each name shall denote a signal for which reading is permitted. If no sensitivity clause appears, the sensitivity set is constructed according to the following (recursive) rule:
The sensitivity set is initially empty. For each primary in the condition of the condition clause, if the primary is
— A simple name that denotes a signal, add the longest static prefix of the name to the sensitivity set.
— An expanded name that denotes a signal, add the longest static prefix of the name to the sensitivity set.
— A selected name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set.
— An indexed name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set and apply this rule to all expressions in the indexed name.
— A slice name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set and apply this rule to any expressions appearing in the discrete range of the slice name.
...
This rule is also used to construct the sensitivity sets of the wait statements in the equivalent process statements for concurrent procedure call statements (11.4), concurrent assertion statements (11.5), and concurrent signal assignment statements (11.6). Furthermore, this rule is used to construct the sensitivity list of an implicit wait statement in a process statement whose process sensitivity list is the reserved word all (11.3).
What this tells us is that the longest static prefix is sufficient in the sensitivity list.
8.1 paragraph 7:
A static signal name is a static name that denotes a signal. The longest static prefix of a signal name is the name itself, if the name is a static signal name; otherwise, it is the longest prefix of the name that is a static signal name. ...
With a non-null range for inp, using parentheses instead of square brackets your mux_41 could be expressed:
library ieee;
use ieee.std_logic_1164.all;
entity mux_41 is
port (
inp: in std_logic_vector (3 downto 0);
outp: out std_logic;
sel: in std_logic_vector (1 downto 0)
);
end entity mux_41;
architecture behavioral of mux_41 is
begin
process (sel, inp)
begin
if sel = "00" then
outp <= inp(0);
elsif sel = "01" then
outp <= inp(1);
elsif sel = "10" then
outp <= inp(2);
else
outp <= inp(3);
end if;
end process;
end architecture behavioral;
Here with the process sensitivity list supplied with the longest static prefix.
This code will analyze (compile) successfully.
So far I have this code for a 2-bit comparator.
module twobitcomparator(xgtyin,xety,xltyin,x1,x0,y1,y0,xgty,xety,xlty);
//I/O
output xgty, xety, xlty; //xgty - x>y, xlty - x<y, xety - x=y
input x1, x0, y1, y0, xgtyin, xetyin, xltyin;
//specify circuit behavior
assign r = (xgyin);
assign s = (xlyin);
assign t = (xetyin);//not sure if I need an xetyin
assign a = (x1&~y1);
assign b = (x1&x0&~y0);
assign c = (x0&~y1&~y0);
assign xgty = (a|b|c|r);//X>Y
assign d = (~x0&~y0);
assign e = (x0&y0);
assign f = (x1&y1);
assign g = (~x1&~y1);
assign xety = ((d|e)&(f|g));//X=Y
assign h = (~x1&~x0&y0);
assign i = (~x1&y1);
assign j = (~x0&y1&y0);
assign xlty = (h|i|j|s);//X<Y
endmodule
Does this look good? I wrote a testbench for it and looked at the wave and the outputs were correct for the inputs, but I'm not sure if it's the most efficient way.
For the cascading, I know that the highest bit comparator's result (if it is an inequality) will just need to be sent down through the rest of the comparators and that will be the final result. If they are equal, then I just have to find the highest bit comparator where there is an inequality and that needs to be cascaded like I mentioned.
I am stuck on getting them to cascade, I am very new to Verilog and I have no clue how I should get each comparator's result into the next one. Here is my attempt.
module ncompare#( parameter n = 2)(input [2*n-1:0] xgyin, xlyin,
input [2*n-1:0] x1, x0, y1, y0,
output [2*n-1:0] xgy, xey, xly,
output xqyout);
wire xqyin;
assign xqyin = 1'b0;
twobitcomparator s1(.xgyin(xgyin[xqyin]), .xlyin(xlyin[xqyin]),
.x1(x1[2*n-1]), .x0(x0[2*n-2]), .y1(y1[2*n-1]), .y0(y0[2*n-2]),
.xgy(xgy[ripple0]), .xey(xey[ripple1]), .xly(xly[ripple2]));
twobitcomparator s0(.xgyin(xgyin[ripple0]), .xlyin(xlyin[ripple2]),
.x1(x1[1]), .x0(x0[0]), .y1(y1[1]), .y0(y0[0]),
.xgy(xgy[ripple3]), .xey(xey[ripple4]), .xly(xly[ripple5]));
endmodule
I think I need to use a generate statement since I need to make it work for any parameter n but I have no clue how to use generate since all examples I've looked at only have one output and I have three (that are also the next comparator's inputs! Agh!)
Thanks for any and all help!
The 2-bit comparator module can be rewritten as
module twobitcomparator(xgtyin,xltyin,x,y,xgty,xlty,xety);
output xgty, xety, xlty;
input xgtyin, xltyin;
input [1:0] x,y;
assign xgty = xgtyin | (~xltyin & ((x[1] > y[1]) | ((x[1] == y[1]) & (x[0] > y[0]))));
assign xlty = xltyin | (~xgtyin & ((x[1] < y[1]) | ((x[1] == y[1]) & (x[0] < y[0]))));
assign xety = ~(xlty | xgty);
endmodule
I have treated the two bit input as a bus instead of treating them as individual bits (Verilog allows you to do that). I have trimmed out the numerous intermediate results that were present in your code. This makes the code easier to understand as you do not have to keep track of all those temporary wires.
I then simulated this module using Icarus Verilog on EDA Playground. The link is here
https://www.edaplayground.com/x/5KRL
A four-bit comparator that uses these twobitcomparators can be written as follows.
module fourbitcomparator(xgtyin,xltyin,x,y,xgty,xlty,xety);
output xgty, xety, xlty;
input xgtyin, xltyin;
input [3:0] x,y;
wire xgty_1,xlty_1,xety_1;
twobitcomparator u_1 (
.xgtyin(xgtyin),
.xltyin(xltyin),
.x(x[3:2]),
.y(y[3:2]),
.xgty(xgty_1),
.xlty(xlty_1),
.xety(xety_1)
);
twobitcomparator u_0 (
.xgtyin(xgty_1),
.xltyin(xlty_1),
.x(x[1:0]),
.y(y[1:0]),
.xgty(xgty),
.xlty(xlty),
.xety(xety)
);
endmodule
Finally a 2n bit comparator using twobitcomparators, can be generalised as follows
module twoN_bitcomparator #(
parameter N = 2
)(
input xgtyin,
input xltyin,
input [(2*N-1):0]x,
input [(2*N-1):0]y,
output xgty,
output xlty,
output xety
);
wire [N:0] xgty_w,xlty_w,xety_w;
assign xgty_w[N] = xgtyin;
assign xlty_w[N] = xltyin;
generate
genvar i;
for (i=0;i<=(N-1);i=i+1)
begin:TWOBITGEN
twobitcomparator u_1 (
.xgtyin(xgty_w[i+1]),
.xltyin(xlty_w[i+1]),
.x(x[(2*i+1) : (2*i)]),
.y(y[(2*i+1) : (2*i)]),
.xgty(xgty_w[i]),
.xlty(xlty_w[i]),
.xety(xety_w[i])
);
end
endgenerate
assign xgty = xgty_w[0];
assign xlty = xlty_w[0];
assign xety = xety_w[0];
endmodule
The simulation of this generalised module is also available on EDA playground at https://www.edaplayground.com/x/2fbr
The waveform for the small testbench is also available at https://www.edaplayground.com/w/x/27X
I have used VHDL all my life and only been using Verilog for a short time, I have to create a logic in Verilog for a very large array and assign it to 1 or 0 depending on the condition of an input.
Here is my VHDL code
if (data_track == '1' ) then
my_array(MAX-1:MIN) <= (others=> '1');
else
my_array(MAX-1:MIN) <= (others=> '0');
end if;
MAX and MIN are parameters for the block, set during the synthesis depending on the type of system we are accessing.
Is there a way to do this in Verilog easily?
A mix of parameter with curly braces will help in resolving (the inner curly brace will act as replication operator)
Code eg:
parameter MAX = 16;
assign high_val = 1'b1;
assign low_val = 1'b0;
if ( data_track ==1'b1)
my_array[MAX-1:MIN] <= {MAX{high_val}};
else
my_array[MAX-1:MIN] <= {MAX{low_val}};
Here in the above code the if statement with curly brace will propogate MSB to LSB with 1 values resulting in all 1's in our case 16 then result will be a 16'b1111111111111111 and it is the vice versa for else condition
Assuming that data_track is one bit wide, then this can be collapsed into one line by replicating the data_track input and assigning it to my_array:
assign my_array[MAX-1:MIN] = {(MAX-MIN){data_track}};
timescale 1ns/10ps
/* resource counter for nor gates
*/
module global_vars;
integer count;
endmodule
module my_nor(y, a, b);
output y;
input a, b;
global_vars gv;
/* at instantiation increment the resources used */
gv =gv +1;
/* add 2ns inherent delay */
nor #2 nor1(y,a,b);
endmodule
When I compile, there is one syntax error at global_vars gv;
I have no idea. Should I initial the gv?
In verilog you can not just do this:
gv = gv +1;
wire types need to use assign:
wire gv;
assign gv = a + b;
reg types can use initial, always #* or always #(posedge clk).
always #* begin
gv = a + b;
end
Your trying to use an instance like a variable, I am not sure what your trying to do with your global_vars, may be make a global variable but creating an instance would make it local not global. Here you would do just as well to make gv an integer rather than an instance.
Note
Wire assignment and always #* are combinatorial, is there is no time delay in the assignment, therefor the value can not be directly referenced to itself. For example
gv = gv + 1;
Is a combinatorial loop, when do you expect the +1 to happen. This is normally solved by making gv a flip-flop and updating its value on a clock edge:
always #(posedge clk) begin
gv <= gv + 1;
end
In this case you still need to set an initial value for gv. for FPGAs this can be done using an initial or an async reset for ASIC.
FPGA using initial:
initial begin
gv = 'b0;
end
always #(posedge clk) begin
gv <= gv + 1;
end
Or for ASIC using reset:
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
gv <= 'b0;
end
else begin
gv <= gv + 1;
end
end
It looks like you are trying to embed a reference to a global variable within a synthesizable module so that you can count how many times that module has been instantiated. As #Morgan has already pointed out, you can't reference a module instantiate as a variable. But there is an even more fundamental problem -- you are trying to mix behavioral code (i.e. global variables) into synthesizable code and that just doesn't work.
Creating a synthesized module is really a two step process -- design and then coding. In the design phase, you figure out what kind of logic you are trying to create. You don't need to go down to the gate level, but you should be able to sketch out the function with clouds of combinatorial logic, registers, FIFOs, memories etc. Once you've gained some familiarity with the language, this may strictly be a mental process rather than something committed to paper, but you still need to think about the logic you are creating. Then once you have designed your circuit, you actually go write the code to implement your design.
Global variables do not exist in hardware. You can make a counter that is accessible by multiple modules, but but it would need some sort of arbitration process. But what you're trying to do is create a run-time counter that counts up the number of modules instantiated, for which there is no hardware analog. You could use 'define statements to instantiate a variable number of modules and have a signal from each module which is defined as '1' if the module is instantiated and '0' if it isn't and then count the number of '1's, but that is self defeating since you already had to define a macro telling you the number of modules before you instantiated them! In which case, you might as well just use the macro value directly and dispense with all the extra signals.
In this other question I asked I got some general advice regarding my module.
Now I seek advice here since I noted that the Verilog community has more users.
I am trying to implement into an existing framework a Most Significant Bit (MSB) operation.
The idea is as follows: I am getting 32 bit complex samples in from ddc_out_strobe, which are 16 bit I and 16 bit Q.
My idea is to combine 4 "cutted" samples into a new sample to feed to the output bb_sample. This is done by getting the 4 MSB out of I0,Q0,I1,Q1,I2,Q2,I3,Q3 (4*8 = 32 bit total) and wiring them every 4th bb_strobe to bb_sample.
Here you can see my implementation:
module my_rx_dsp0_custom
#(
//frontend bus width
parameter WIDTH = 24
)
(
//control signals
input clock, //dsp clock
input reset, //active high synchronous reset
input clear, //active high on packet control init
input enable, //active high when streaming enabled
//user settings bus, controlled through user setting regs API
input set_stb, input [7:0] set_addr, input [31:0] set_data,
//full rate inputs directly from the RX frontend
input [WIDTH-1:0] frontend_i,
input [WIDTH-1:0] frontend_q,
//full rate outputs directly to the DDC chain
output [WIDTH-1:0] ddc_in_i,
output [WIDTH-1:0] ddc_in_q,
//strobed samples {I16,Q16} from the RX DDC chain
input [31:0] ddc_out_sample,
input ddc_out_strobe, //high on valid sample
output ddc_out_enable, //enables DDC module
//strobbed baseband samples {I16,Q16} from this module
output [31:0] bb_sample,
output bb_strobe //high on valid sample
);
reg [3:0] i_msb;
reg [3:0] q_msb;
reg [31:0]temp_buff = 0;
reg [31:0]my_zeros = 0;
reg [1:0] count = 0;
always #(posedge clock)
if(ddc_out_strobe) begin
i_msb <= ddc_out_sample[31:28];
q_msb <= ddc_out_sample[15:12];
temp_buff <= {i_msb,q_msb,temp_buff[31:24]};
// to avoid if-else conditions
count <= (count==2'd3) ? 2'd0 : (count+1);
end
// to avoid if-else conditions
assign bb_strobe = (count==2'd3) ? 1'b1 : 1'b0;
assign bb_sample = (count==2'd3) ? temp_buff : my_zeros;
assign ddc_out_enable = enable;
assign ddc_in_i = frontend_i;
assign ddc_in_q = frontend_q;
endmodule //my_rx_dsp0_custom
(1) When trying to build the FPGA images I get the following warning (I just show you the one for 23, but it is the same for other ones):
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch <temp_buff_23> has a constant value of 0 in block <my_rx_dsp0_custom>. This FF/Latch will be trimmed during the optimization process
I have searched this problem in SE and found some good explanations on what might be going wrong, here or here for example.
What I understand is the following: temp_buff <= {i_msb,q_msb,temp_buff[31:24]}; is a conflictive line since the <= operator is getting the old values from i_msb and q_msb, and not the ones from the MSB operation.
(2) I tried avoiding if-else conditions to allow me to declare some things out of the always #* block (this way I avoid having a wire on the LHS of an always block, which is not allowed).
Are my conditionals correct?
As I explained before, I want only every 4th bb_sample to be assigned.
Is assign bb_strobe = (count==2'd3) ? 1'b1 : 1'b0; getting the effect I want despite not being in the always #(posedge clock) block?
If other infos are needed, please let me know. This is part of a much bigger project that I am trying to modify for my purposes.
(1) The trimmed FF/Latch warning is not due to non-blocking assignments. It is from 24 bits of the temp_buff register always being assigned to zeros. The RHS is 16bits; i_msb (4 bits), q_msb (4 bits), and temp_buff[31:24] (8 bits). And you are assigning it to a 32bit value. The assignment:
temp_buff <= {i_msb,q_msb,temp_buff[31:24]};
Is equivalent to:
temp_buff <= {16'h0000, i_msb,q_msb,temp_buff[31:24]};
This means temp_buff[31:16] will always be zero can can be optimized out. temp_buff[7:0] can also be optimized out to constant zeros because it is assigned to temp_buff[31:24] which is a constant 0. Perhaps you meant you shift right 8 bits like so:
temp_buff <= {i_msb,q_msb,temp_buff[31: 8 ]};
(2) You are correct that wires should not be assigned with any always block (or initial block). However you could have turned the wire to a reg. It is a miss conception that reg is for registers only (FF/Latches). reg in a properly coded combinational block will create combinational logic (no FF or Latches). Property meaning the reg is assigned within every branching condition withing the always block, else it infers a latch. Example
module my_rx_dsp0_custom
/* ... your original code ... */
output reg [31:0] bb_sample,
output reg bb_strobe //high on valid sample
);
/* ... your original code ... */
always #(posedge clock)
if(ddc_out_strobe) begin
temp_buff <= {i_msb,q_msb,temp_buff[31:8]};
count <= (count==2'd3) ? 2'd0 : (count+1);
end
always #*
begin
i_msb = ddc_out_sample[31:28];
q_msb = ddc_out_sample[15:12];
bb_strobe = (count==2'd3);
bb_sample = bb_strobe ? temp_buff : 32'd0;
end
assign ddc_out_enable = enable;
/* ... your original code ... */