Circular Buffer: Selecting Range of Indices that Include the Wraparound Point - verilog

I think this question is best understood with an example. So here we go:
Imagine the following are defined:
parameter number_of_points_before_point_of_interest = 4;
logic [15:0] test_data = 16'b0000111100001111;
logic [3: 0] point_of_interest;
logic [7: 0] output_data;
if the value assigned to point_of_interest is 1 and the value to number_of_points_before_point_of_interest is 4. I want my output_data to be {test_data[E: F], test_data[5:0]} or 8'b00111100.
So in essence, I want to take 8 bits starting from (point_of_interest - number_of_points_before_point_of_interest) and ending at (point_of_interest
- number_of_points_before_point_of_interest + 7).
Since point_of_interest is a variable number, the following two indexing methods are invalid:
To make the code more concise: point_of_interest --> pot
number_of_points_before_point_of_interest --> num_pt_before_pot
buffer[pot - num_pt_before_pot: 4'hF] // Invalid since pot not constant
buffer[pot -: num_pt_before_pot] // Part-select doesn't work either
Note: Variability of pot is not an issue in the second case since starting point can be variable. Regardless, part-select does not provide the desirable results in this example.
Your help is very much appreciated. Thanks in advance

A simple trick you can do is replicate your test_data, then take a slice of it
output_data = {2{test_data}}[16+pot-before_pot-:2*before_pot];

Related

Weight function calculation for dynamic output

I am trying to prepare a weight function whose output should lie in (min_output_value, max_output_value) and the output depends on the difference of actual and target value of y, i.e. (y_actual, y_target).
The output value should tend towards the max_output_value if (y_actual - y_target) is more and if the difference is less, the output value should tend to min_output_value.
Any link pointing to the answers are also appreciated.
After some R&D, I came up with a solution, which as follows:
y_diff = absolute(y_target - y_actual)
denominator = (1 + exp(-(min_output_value/10)*y_diff ))
output = (max_output_value/ denominator)
This ensures that the output value always lies in the range [min_output_value, min_output_value]
Rounding is optional.

Verilog assign statement result check

new to Verilog (well, SystemVerilog really, but I found that for the very basic keywords like assign and initialize I am able to learn from Verilog resources as well). I am following example 2 on this link chipverify example 2. It's simple so I'll write it down. I feel as if they've made a mistake, but since I am a newbie it's hard to know if my feeling is correct or not.
module xyz (input [3:0] x, //let x='hC or x='b1100 for this example's purposes
input y, //y is a 1bit scalar y='h1 = 'b1
output [4:0] z);
//case 8
assign z = {3{y}};
endmodule
For case 8, they are saying that z will result in z='b00111. I don't think it's correct! Following their case 3, where z only got bits [4:1] assigned,it stated that the reaming bit will be undriven and thus result in high impedance Z. Shouldn't the result of case 8 then be z ='bZZ111 and not z='b00111?
Let me know, thanks! =)
From section 10.7 (Assignment extension and truncation) in IEEE Std 1800-2017 (the SystemVerilog standard),
When the right-hand side evaluates to fewer bits than the left-hand side, the right-hand side value is padded to the size of the
left-hand side.
In your case, {3{y}} is an unsigned value, so it is 0-padded to 5 bits, that is 5'b00111, and then assigned to z.

Verilog - masking using 1 bit input

I have a situation I'm not sure what's the right syntax that exists which can solve it.
In my code I have
reg [N-1:0] bit_list;
and another variable n which counts how many bits I inserted into bit_list.
Occasionally and according to the input - I need to, during a single posedge, shift bit_list by 1 then change bit_list[N-n] to my input. My idea was I can do the following
bit_list<=bit_list<<1 || X
Where X should be replaced some N-1 long vector that has zeros in all bits except for N-n. The problem is I don't know to describe such a vector - Hence my question.
I'm sure my problem is simple enough to be solved in a variety of simple ways, so any solution to my problem will work.
Sorry if my question is noobish as I'm still new, help will be appriciated of course.
You can use a mask. (BTW || is logical-or, you want | a bitwise-or)
reg [N-1:0] mask;
mask = ({ {N{1'b0}},1'b0}) << n) - 1; // the concat is needed in case N > 32
bit_list<=((bit_list<<1) & ~mask) | (X & mask);

what is this command in Verilog

I am new to verilog and I was reading few codes online. I came across the following line of code and didn't understand what exactly this means
wr_ptr_reg <= {ADDR_WIDTH + 1{1'b0}};
I would appreciate if someone could explain what it means
1'b0 describes a 1-bit wide binary zero value. <n>{<value>} gives a bit vector formed by concatenating n copies of the bit vector value. In this case, it creates a bit vector containing ADDR_WIDTH + 1 copies of 0 bits. ADDR_WIDTH will be a previously declared parameter representing some constant value (probably stored as an integer, which is basically a 32-bit bit vector). Then you are storing zero to wr_ptr_reg. <= indicates a non-blocking assignment. This basically means that its value will not be updated until the rest of the current block is finished. You can treat all non-blocking assignments in a block as if they happen at the same time when the block finishes.
It would be much clearer to add parenthesis:
wr_ptr_reg <= {(ADDR_WIDTH + 1){1'b0}};
{..} is a concatenation operator. { count { vector } } means concatenate the vector count times.
In this case the vector is a single bit which is repeated ADDR_WIDTH + 1 times.
Thus you get a vector consisting of (ADDR_WIDTH + 1) zeros.
This is another example: { 4 { 3'b101} } is equal to 12'b101101101101
Thus you set the wr_ptr_reg to all zero's (assuming wr_ptr_reg consists of ADDR_WIDTH + 1 bits)

Using real parameter to determine counter sizes

I am trying to make my debounce code more modular by passing in parameters that are the frequency and the desired bounce time to eliminate button/switch bounce. This is how I approached it:
module debounceCounter
#(
parameter CLOCK_FREQUENCY_Hz = 50_000_000,
parameter BOUNCE_TIME_s = 0.003
)
(
input wire sysClk, reset,
input wire i_async,
output reg o_sync
);
/* include tasks/functions */
`include "clog2.v"
/* constants */
parameter [(clog2(BOUNCE_TIME_s * CLOCK_FREQUENCY_Hz + 0.5) - 1) : 0]
MAX_COUNT = BOUNCE_TIME_s * CLOCK_FREQUENCY_Hz;
Synthesis using Xilinx ISE 14.7 Throws this error:
Xst:850 - "../../rtl/verilog/debounceCounter.v" line0: Unsupported real
constant
How can I get around this issue so that I can determine the counter size and max count value based on parameters being passed in from code above this module in the heirarchy? A majority of my code has sizes of variables and such determined by frequency generics, so not being able to use methods like VHDL has proven to create problems in my designs.
Seems to work fine on Vivado 2016.3 (the oldest I have available). I think the problem is that 2014.7 is too old to support this. You didn't show the contents of the `include, but I'm assuming its the one from AR# 44586. If so, it should take and return integers and it will truncate the real floating point values for you. Floating point arithmetic is fine to use in Verilog/SystemVerilog testbenches and parameters.
How can I get around this issue so that I can determine the counter
size and max count value based on parameters being passed in from code
above this module in the heirarchy?
Update to a recent version. 2017.1 or 2017.3 are working good for me. I tested the following on 2016.3 and it also worked fine.
Try using SystemVerilog (.sv) which supports the $clog2() system function natively without the `include. Not sure when .sv started working, but probably needs 2015+.
Verify that your version of clog2 in the clog2.v header matches the following
NOTE: There is another pretty serious bug in the code you posted.
When you want to get the MSB required to hold a constant expression "x" the pattern should be $clog2((x)+1)-1. You have only added 0.5 instead of 1. This causes there to not be enough bits whenever the result of the floating point expression "x" falls between 2^n and (2^n + 0.5). For example, what you have erronously computes the constant as 17'h0 instead of 18'h4_0000 for the the frequency 87381333 but it still appears to work for your example at 50Mhz. Murphy's law says you will accidentally fall into this narrow bad range at the worst possible time, but never during testing :).
For reference, this is what I tested, with the `include expanded inline:
`timescale 1ns / 1ps
module debounceCounter
#(
//parameter CLOCK_FREQUENCY_Hz = 50_000_000,
parameter CLOCK_FREQUENCY_Hz = 87381333, // whoops
parameter BOUNCE_TIME_s = 0.003
)
(
input wire sysClk, reset,
input wire i_async,
output reg o_sync
);
/* include tasks/functions */
//`include "clog2.v"
function integer clog2;
input integer value;
begin
value = value-1;
for (clog2=0; value>0; clog2=clog2+1)
value = value>>1;
end
endfunction
/* constants */
//parameter [(clog2(BOUNCE_TIME_s * CLOCK_FREQUENCY_Hz + 0.5) - 1) : 0] // <- BUG!!! 0.5 should 1
parameter [(clog2(BOUNCE_TIME_s * CLOCK_FREQUENCY_Hz + 1) - 1) : 0]
MAX_COUNT = BOUNCE_TIME_s * CLOCK_FREQUENCY_Hz;
initial
$display("MAX_COUNT %d", MAX_COUNT);
endmodule
Type Real is not synthesizable. Draw/Create your design before you translate into/write HDL and you will realize this. Ask yourself, "What does a real synthesize to in gates?"
For those tools (e.g. Synplify) that do "support" Type Real, it is just a vendor interpretation, and as such is impossible to "support" since it is not defined as part of any HDL standard. The implication: If you had a simulator that interprets Type Real one way, and your synthesizer (likely) interprets it another way, you will get sim/syn mismatches. You may get away with them, depending on what you are trying to accomplish, but, it would still be considered poor design practice.
Behavioral code, for modeling and use in testbenches, as stated above, a different story as it is not synthesized.

Resources