# Verilog width expansion and reduction operator equivalence?

#1

I’m using MyHDL on some of my small projects, and I want to implement some simple functions using width expansion and reduced unary operator, like following snippets as in verilog:

``````// svalid: 1-bit; en, dready: 4-bit
// width expansion
assign dvalid = {NUM_W{svalid}} & en;

//  reduced or
``````

But i dont have a clue how to code them using MyHDL.
Could somebody give me a hint on that ?

Regards!

#2

There will a few different opinions on your question.
IMHO you are swapping the cart and the horse. Obviously you know Verilog quite well (I don’t …) and you are asking whether there is an equivalent way to write this in MyHDL. The idea behind MyHDL is that we write standard Python to simulate (first) and convert (second) to an intermediate representation, at the time VHDL or Verilog.
The question becomes: do we have a Python construct that later in conversion can come out in the desired format(s)?
The way I would (currently do) write this:

``````from myhdl import Signal, intbv, block, always_comb

@block

@always_comb
def assign():
for i in range(len(en)):
dvalid.next[i] = svalid and en[i]

return assign

if __name__ == '__main__':

def convert():
en, dready, dvalid = [Signal(intbv(0)[4:]) for _ in range(3)]
sready, svalid = [Signal(bool(0)) for _ in range(2)]

dfc.convert(hdl='Verilog')
dfc.convert(hdl='VHDL')

convert()
``````

produces this Verilog:

``````// File: vwe.v
// Generated by MyHDL 0.10
// Date: Sat Oct  6 11:50:18 2018

`timescale 1ns/10ps

module vwe (
svalid,
en,
dvalid
);

input svalid;
input [3:0] en;
output [3:0] dvalid;
reg [3:0] dvalid;

always @(en, svalid, dready) begin: VWE_ASSIGN
integer i;
for (i=0; i<4; i=i+1) begin
dvalid[i] = (svalid && en[i]);
end
end

endmodule
``````

Which will work fine, but alas doesn’t have the conciseness of the Verilog code you presented.

Ideally you want to write something like:

``````@block

@always_comb
def assign():
dvalid.next[i] = bitextend(svalid, NUM_W) and en[i]

return assign
``````

Assuming we have the function bitextend defined (as a built-in?) to do what it needs to do, this code will simulate fine. It does convert fine too, but instead of the targeted Verilog construct it will include a function.

``````function [4-1:0] MYHDL2_bitextend;
input [1-1:0] b;
input w;
integer w;
reg [4-1:0] r;
integer i;
begin: MYHDL5_RETURN
r = 4'h0;
for (i=0; i<w; i=i+1) begin
r[i] = b;
end
MYHDL2_bitextend = r;
disable MYHDL5_RETURN;
end
endfunction

assign dvalid = (MYHDL2_bitextend(svalid, 4) & en);

endmodule
``````

Now we could make the converter(s?) smarter and if we define a number of functions as built-in we could have the converter recognise them and implement the appropriate construct.
But I am sure that there are other priorities to extend MyHDL.
@cfelton, @hgomersall, and others … Your ideas?

#3

@josyb captured the gist. Furthermore, since the reduction is only combinatorial logic you can write a function for this operation: `reduce_and(bitvector: intbv)`, `reduce_or(bitvector: intbv)`. If you do this the Python gods will be quite pleased as your code readability has improved immensely .

This is the scenario us VHDL’ers (although it has been years since I have done serious VHDL) have always been in. In my opinion the functions gives you more options, example you can add a warning if you are reducing too many bits.