# Verilog width expansion and reduction operator equivalence?

**URL:** <https://discourse.myhdl.org/t/verilog-width-expansion-and-reduction-operator-equivalence/335>\
**Category:** Support\
**Created:** [October 6, 2018, 4:18am UTC](https://discourse.myhdl.org/t/verilog-width-expansion-and-reduction-operator-equivalence/335 "2018-10-06T04:18:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![greatshuyi](https://avatars.discourse-cdn.com/v4/letter/g/a587f6/32.png) [@greatshuyi](https://discourse.myhdl.org/u/greatshuyi)\
**Post date:** [October 6, 2018, 4:18am UTC](https://discourse.myhdl.org/t/verilog-width-expansion-and-reduction-operator-equivalence/335/1 "2018-10-06T04:18:53Z")

</div>

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:

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

// reduced or
assign sready = | (dready & en)

```

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

Regards!

---

<div class="post-metadata">

**Author:** ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)\
**Post date:** [October 6, 2018, 10:19am UTC](https://discourse.myhdl.org/t/verilog-width-expansion-and-reduction-operator-equivalence/335/2 "2018-10-06T10:19:03Z")

</div>

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:

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

@block
def vwe(svalid, en, dready, sready, dvalid):

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

        sready.next = 1 if (dready & en) else 0

    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 = vwe(svalid, en, dready, sready, dvalid)
        dfc.convert(hdl='Verilog')
        dfc.convert(hdl='VHDL')

    convert()

```

produces this Verilog:

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

`timescale 1ns/10ps

module vwe (
	svalid,
	en,
	dready,
	sready,
	dvalid
);

	input svalid;
	input [3:0] en;
	input [3:0] dready;
	output sready;
	reg sready;
	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
		sready = (dready & en) ? 1 : 0;
	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:

```python
@block
def vwe(svalid, en, dready, sready, dvalid):

    @always_comb
    def assign():
        dvalid.next[i] = bitextend(svalid, NUM_W) and en[i]
        sready.next = 1 if (dready & en) else 0

    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.

```auto
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);
assign sready = (dready & en) ? 1 : 0;

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?

---

<div class="post-metadata">

**Author:** ![cfelton](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/cfelton/32/3_2.png) [@cfelton](https://discourse.myhdl.org/u/cfelton)\
**Post date:** [October 6, 2018, 1:20pm UTC](https://discourse.myhdl.org/t/verilog-width-expansion-and-reduction-operator-equivalence/335/3 "2018-10-06T13:20:26Z")

</div>

@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](https://electronics.stackexchange.com/questions/85922/vhdl-or-ing-bits-of-a-vector-together) 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.
