I have tried looking for the answer to this, but to no avail. I am getting problems when I re-synthesise my code and I suspect that it is due to clock issues.
I am using a DCM to multiply an external crystal oscillator from 25MHz to 50MHz. However, I think that the tool won't know what frequency the crystal oscillator actually is, since it is an external physical component. My code is below:
//since our crystal oscillator is only 25Mhz, we use a DCM to multiply it by two since the desired is 50Mhz
DCM #(
.CLKFX_DIVIDE (2),
.CLKFX_MULTIPLY (4)
) dcm_master (
.CLKFB (CLK_FB),
.CLKIN (CLK_crystal),
.RST (DcmReset),
.CLK0 (MasterClk0Unbuf),
.CLK90 (),
.CLK180 (),
.CLK270 (),
.CLK2X (),
.CLK2X180 (),
.CLKFX (MasterClkFxUnBuf),
.CLKFX180 (),
.CLKDV (),
.LOCKED (DcmLocked),
.STATUS (),
.PSCLK (1'b0),
.PSEN (1'b0),
.PSINCDEC (1'b0),
.PSDONE ()
);
//we provide feedback to the DCM's phase input (possibly not neccessary)
BUFG bufg_master_dcm_clk_0 ( .I(MasterClk0Unbuf), .O(CLK_FB) );
BUFG bufg_master_dcm_clk_fx ( .I(MasterClkFxUnBuf), .O(CLK_FX) );
//code taken from xilinx. We toggle using a bufgmux between the onboard and external clock
// BUFGMUX: Global Clock Buffer 2-to-1 MUX
// Spartan-3
// Xilinx HDL Libraries Guide, version 13.2
BUFGMUX BUFGMUX_inst (
.O(CLK), // Clock MUX output
.I0(CLK_FX), // Clock0 input
.I1(CLK_local), // Clock1 input
.S(sw[6]) // Clock select input
);
Will this code in the ucf force the tool to recognize the output of my DCM as 50MHz?
PIN "bufg_master_dcm_clk_fx.O" TNM_NET = CLK50;
TIMESPEC TS_CLKBuf = PERIOD "CLK50" 100 MHz HIGH 50%;
Furthermore, am I using the BUFG's correctly? Xilinx says I should use an IBUFG to connect the external clock into my DCM, and I am getting errors saying my BUFG's can only address half the chip (which I imagine is going to become troublesome).
thanks,
Nathan
I think your clock constraints are off. You should be constraining the input to the DCM -- the DCM knows what to do with the outputs. Here's what I would use:
NET clk_in TNM_NET = tnm_clk_in;
TIMESPEC TS_clk_in = PERIOD tnm_clk_in 40ns;
where clk_in is the crystal (CLK_crystal in your case). Make sure that the crystal is connected to a clock pin on your device.
I would have liked to test this out first. For the Spartan-3 family of FPGAs, using one of the DCMs. This is the template that ISE produces.
Notice that there is a dedicated CLK2X.
Also, based on the user manual: .CLKFB should be driven by a BUFG source.
wire i_FeedBack;
wire o_FeedBack;
BUFG clkFBBuf(
.I(i_FeedBack),
.O(o_FeedBack)
);
DCM #(
[...]
.CLKFX_DIVIDE(1), // Can be any integer from 1 to 32
.CLKFX_MULTIPLY(2), // Can be any integer from 2 to 32
[..]
) DCM_inst (
.CLK0(i_FeedBack), // 0 degree DCM CLK output
.CLK2X(CLK2X), // 2X DCM CLK output
[...]
.CLKFX(CLKFX), // DCM CLK synthesis out (M/D)
.CLKFB(o_FeedBack), // DCM clock feedback
.CLKIN(clk), // Clock input (from IBUFG, BUFG or DCM)
[...]
);
Related
How do I access internal regs/signals without declaring them as input/output.
e.g., consider the following block, A & B are placed in TOP block and I need to access int_A from withing block B without declaring it as output in A and input in B.
You can do that by hierarchical reference.
However as far as I know you can only use that in test-benches.(I have never even dared to use that in RTL).
// Top level test-bench
wire int_A;
assign int_A = dut_0.int_A;
dut dut_0 ( // instance of dut
....
);
If inside the dut you have another instance use the same method:
module dut (
);
core core0 (
);
endmodule // dut
A signal inside the core can now be referenced from the top level as:
assign int_A = dut_0.core_0.int_A;
I have a module which stores a bitmap of different characters, that I am planning on using to display text on a matrix. Currently, the bitmap is populated with a memory initialization file, and this file is passed in as a parameter (I have confirmed this working in Quartus and ModelSim).
In order to actually have a lookup table for all the characters, I wanted to make a separate module which has instantiations of the all bitmaps, and selects the correct one based on a character code. These bitmap instantiations are created in a generate block, and they take the correct filename from an array. However, ModelSim doesn't like this. My code is as follows:
module mem_char_disp_lib(
output logic pixel,
input logic [4:0] x,
input logic [5:0] y,
input logic [6:0] code,
input logic clk
);
localparam CHAR_NUM = 26;
logic [CHAR_NUM-1:0] alphabet;
const var [CHAR_NUM-1:0] BITMAPS = {
"/mem/char/A.hex",
"/mem/char/B.hex",
"/mem/char/C.hex",
// ... a lot more declarations here...
"/mem/char/X.hex",
"/mem/char/Y.hex",
"/mem/char/Z.hex"
};
genvar i;
generate
for (i=0; i<CHAR_NUM; i=i+1) begin : mem_char_disp_blocks
mem_char_disp #(.BITMAP(BITMAPS[i])) block (
.pixel(alphabet[i]),
.x, .y, .clk,
.code(i),
.data(1'b0),
.write_en(1'b0)
);
end
endgenerate
always_comb
pixel = alphabet[code];
endmodule
The error ModelSim is giving me is:
The expression for a parameter actual associated with the parameter name ('BITMAP') for the module instance ('block') must be constant.
(referring to the line inside the for loop)
I am not sure why this doesn't work. On a hardware level, it seems like I'm just making a lot of copies of a module, and slightly tweaking each one with a constant parameter known at compile-time. Is there some basic syntax that I'm missing?
Edit: I have also tried the following code, which seems to give a runtime error:
for (i=0; i<CHAR_NUM; i=i+1) begin : mem_char_disp_blocks
parameter [CHAR_NUM-1:0] BITMAPS = {
"/mem/char/A.hex",
// more elements...
"/mem/char/Z.hex"
};
mem_char_disp #(.BITMAP(BITMAPS[i])) block (
.pixel(alphabet[i]),
.x, .y, .clk,
.code(i),
.data(1'b0),
.write_en(1'b0) );
end
The error is Module parameter 'BITMAP' not found for override. (One of these errors for each of the generated modules; CHAR_NUM total.) This doesn't make sense to me, since instantiating a single one directly works just fine (e.g. mem_char_disp #(.BITMAP("/mem/char/A.hex") block /* ... */).
A const variable is not a constant - it is a write-once variable that gets initialized at runtime when the variable gets allocated. You need to us a parameter or localparam to assign to another parameter as you discovered in your update. You also need to fix the dimensions of the array
parameter bit [1:15*8] BITMAPS[26] = {
"/mem/char/A.hex", // 15 8-bit chars
// more elements...
"/mem/char/Z.hex" // 26 elements
};
Can't help you with your last error without seeing the declaration of the module mem_char_disp
I have designed a module (A) in Verilog and I need to instantiate it four times in a top module. The two modules communicate with each other and some other modules. 'A' sends out some signals which the other instantiation of 'A' should accept. The signals are sent through an interface or a bus. I do not want to complicate the design by incorporating any standard bus protocols. I have created an inout port to avoid having the same type of ports for input as well as output.
Is there any way to assign an id or a code to every instantiation, so that every instantiation checks for that id and accepts the signals coming from a different ID than itself. Right now without the id or a standard bus protocol, the modules are accepting their own signals too which is not supposed to happen.
Here ways you can do this:
Add an ID input port When this port is tided to a constant, at power-up the device can detect its ID. Technically you could do dynamic ID with this, but usually you just connect the port to a constant value. This is the most flexible option, especially if you want your end product to be used as a configurable component.module A ( /* your_ports */, input [1:0] ID );
/* ... code ... */
endmodule
module top;
A inst0 ( .ID(2'd0), .* );
A inst1 ( .ID(2'd1), .* );
A inst2 ( .ID(2'd2), .* );
A inst3 ( .ID(2'd3), .* );
endmodule
Create an ID parameter Simulate to the ID input port except that the value is hard coded and the instance knows the ID value at compile time, before simulation or device power-up. Unique parameter values generate unique modules. If the ID is 0, it will be physically different than an ID with 1. module A #(parameter ID) ( /* your_ports */ );
/* ... code ... */
endmodule
module top;
A #( .ID(0) ) inst0 ( .* );
A #( .ID(1) ) inst1 ( .* );
A #( .ID(2) ) inst2 ( .* );
A #( .ID(3) ) inst3 ( .* );
endmodule
Why don't you set a parameter for each module and use it as an ID? Then set the parameter uniquely for each instance:
module A;
parameter ID = 0; //default value
case (ID)
0: //specific code for ID0
1: //specific code for ID1
2: //specific code for ID2
3: //specific code for ID3
endcase
endmodule
And your top module:
module top;
A #(.ID(0)) inst_0 (...);
A #(.ID(1)) inst_1 (...);
A #(.ID(2)) inst_2 (...);
A #(.ID(3)) inst_3 (...);
endmodule
A couple of other useful points:
You may want to check generate block or vectorized/array module instantiation, which allow you instantiate an array of modules.
Also, notice that in general, each module can see the entire hierarchy. Inside each module, you can access signals using a hierarchical expression:
module A;
reg s;
....
initial $display("The initial value of signal s in instance A_2 is:", top.inst_2.s);
endmodule
Beware though this is not recommended since your module description would be specific to your hierarchy.
I have an SV assertion which checks the property as below
propert my_property;
#(posedge clk) disable iff(reset) $rose(halt) ##0 ((rx_prio) > (expec_prio)) ##[0:$] $rose(rdy) |-> ##[1:100] (my_prio[rx_prio]==1'b1);
endproperty:my_property
I have the assertion as below:
MY_PROPERTY_CHECK:assert property (my_propert)
else
$error;
Here, the scenario is that, the antecedent is true and the consequent is checked between 1 & 100 clock cycles. After the antecedent, the clock is stopped due to clock gating for some time and then the clock starts ticking again. The signal my_prio[rx_prio] is asserted after the clock gating but again within 100 clock cycles. But I still get the assertion failure.
Not able to figure out the issue of failure. Does the clock gating in between the assertion check has an issue? Or any other reason failure?
Thanks.
There might be many threads starting. Try using local variables with display statements below. See IEEE Std 1800-2012 § 16.10 Local variables
propert my_property;
static int prop_cnt=0; // shared
local int prop_id; // Note: some require the "local", other need it omitted
#(posedge clk) disable iff(reset)
($rose(halt) ##0 ((rx_prio) > (expec_prio)),
prop_id=prop_cnt++,
$display("Spawn prop_id:%0d prop_cnt:%0d # %0t %m",
prop_id,prop_cnt,$time) )
##[0:$] ($rose(rdy),
$display("Trigger prop_id:%0d prop_cnt:%0d # %0t %m",
prop_id,prop_cnt,$time) )
|-> ##[1:100] (my_prio[rx_prio]==1'b1,
$display("Pass prop_id:%0d prop_cnt:%0d # %0t %m",
prop_id,prop_cnt,$time) );
endproperty : my_property
If you see Spawn-Spawn-Trigger, or Spawn-Trigger-Trigger, our anything outside of expected (i.e. Spawn-Triger-Pass) then there are unexpected threads.
If this is the case, then look into IEEE Std 1800-2012 § 16.9.8 First_match operation
first_match(
$rose(halt) ##0 ((rx_prio) > (expec_prio)) ##[0:$] $rose(rdy),
$display("Spawn-Trigger prop_id:%0d prop_cnt:%0d # %0t %m",
prop_id,prop_cnt,$time)
) |-> // ...
OR § 16.9.10 Sequence contained within another sequence
(
( $rose(halt) ##0 ((rx_prio) > (expec_prio)) ) within $rose(rdy)[->1],
$display("Spawn-Trigger prop_id:%0d prop_cnt:%0d # %0t %m",
prop_id,prop_cnt,$time)
) |-> // ...
You might want to create a sequence for the trigger.
As I don't know your setup, I could assume that you are maybe triggering on a clock further up the hierarchy that is not being gated, but you debug waves in the exact hierarchy where the clock is being gated.
If you are writing your assertions for an RTL block that cannot be retrofitted with assertions (it's VHDL/Verilog or you are not allowed to touch the file), use bind to instantiate your assertions inside that block: http://www.asic-world.com/systemverilog/assertions22.html
I have some data from a 1 bit serial port which comes in multiples of bytes of variant lengths as such:
byte expected_1 [$] = {8'hBA, 8'hDD, 8'hC0, 8'hDE};
byte expected_2 [$] = {8'h01, 8'h23, 8'h45, 8'h67, 8'h89, 8'hAB, 8'hCD, 8'hEF};
At each positive clock edge, one bit is sent. I need to testbench hundereds of sequences ( maybe thousand in the future ) so I want to automate the process with assertions in system verilog. The new 2012 standard allows for queues to be passed to properties, but can the queues be sent though a recursive property? I received some error about hierarchical ref.
This is what I have so far (with help from #Greg here):
default clocking sck #(posedge sck); endclocking : sck
sequence seq_serial(logic signal, logic [7:0] expected); // check each bit
byte idx = 7;
(signal == expected[idx], idx--)[*8];
endsequence : seq_serial
property recurring_queue(bit en, logic data, byte data_e [$])
int queue_size = data_e.size;
logic [7:0] expected = data_e.pop_front();
if(queue_size != 0) (
!en throughout (seq_serial(data, expected) ##1 recurring_queue(en, data, data_e))
);
endproperty : recurring_queue
`define ez_assert(exp)
assert property (recurring_queue(en, data, exp))
else $error("Bad Sequence # time: %t. Info: %m", $time);
Calling the assertion in my testbench should be as easy as this:
A1 : `ez_assert(expected_1);
The error messages read:
1) passing hierarchical ref to be used in another hierarchical ref is not supported
2) Illegal SVA property in RHS of'##' expression
3) Local variable queue_size referenced in expression before getting initialized
I'm open to other ideas for asserting long variable-length serial sequences.
Try the same strategy as seq_serial:
sequence seq_queue_pattern(bit en, logic data, byte expt_queue [$]);
int qidx = 0;
( !en throughout (seq_serial(data,expt_queue[qidx]), qidx++)[*] )
##1 (qidx==expt_queue.size);
endsequence : seq_queue_pattern
asrt_expected_1 : assert property ( $fell(en) |-> seq_queue_pattern(en,data,expected_1));
asrt_expected_2 : assert property ( $fell(en) |-> seq_queue_pattern(en,data,expected_2));
This assertion will fail if en is high or the seq_serial chain does not match expected. Do not that parenthicy location matters:
en is don't care one clock after final seq_serial completes:
( !en throughout (seq_serial(data,expt_queue[qidx]), qidx++)[*] ) ##1 (qidx==expt_queue.size)
en must be low one clock after final seq_serial completes or failes and don't care after that
!en throughout ( (seq_serial(data,expt_queue[qidx]), qidx++)[*] ##1
(qidx==expt_queue.size) )
en must be low one clock after final seq_serial completes and don't care after that
!en throughout ( (seq_serial(data,expt_queue[qidx]), qidx++)[*] ##1
(qidx==expt_queue.size) ) ##1 (qidx==expt_queue.size)
Queues within sequences and properties are new and may not be fully supported by all simulators yet. To work around this limitation, use a parametrized macro to create a sequence for each expected queue stream:
`define asrt_qpat(en,monitor, expt_queue) \
sequence seq_queue_pattern__``expt_queue (bit en, logic data); \
int qidx = 0; \
(!en throughout (seq_serial(data,expt_queue[qidx]), qidx++)[*]) \
##1 (qidx==expt_queue.size); \
endsequence : seq_queue_pattern__``expt_queue \
\
asrt_``expt_queue : assert property( #(posedge clk) \
$fell(en) |=> seq_queue_pattern__``expt_queue (en,monitor) ) \
else $error("Bad Sequence # time: %t. Info: %m", $time);
`asrt_qpat(en,data[0],expected_1)
`asrt_qpat(en,data[1],expected_2)