1
\$\begingroup\$

I would like to create a module that can change the value of a register passed to it (+/- 1) using an inout port. I wrote this:

module tune(
    input clk,
    input read,
    input [15:0] x,
    inout [15:0] y,
    input plus,
    input minus
);

reg [15:0] a;
reg [15:0] b;

assign y = read ? a:'bz;

always@(posedge clk) begin
    b<=y;
    a<=x;
    if (plus) b<=b+1;
end

endmodule

When read is HIGH, I expect y to be initialized to the value of x. When read is LOW, I expect to output the value of b (which can be decremented or incremented by using minus or plus). Currently however, plus does not do anything, and read toggles y between 0xFFFF and 2 (when I pass 2'd42 to x).

I admit I do not have a good grasp of non-blocking assignments. What should I change to make my code work, or is there a better way to implement the desired behavior?

\$\endgroup\$
  • \$\begingroup\$ Are you writing this for synthesis, or only for simulation? \$\endgroup\$ – The Photon Nov 30 '14 at 5:57
  • \$\begingroup\$ for synthesis on a Nexys 3 \$\endgroup\$ – Jinkai Nov 30 '14 at 6:17
  • \$\begingroup\$ Are you trying to make a counter with a load function and tristate-buffered outputs? \$\endgroup\$ – The Photon Nov 30 '14 at 6:21
1
\$\begingroup\$

When read is HIGH, I expect y to be initialized to the value of x.

The only thing your code actually does when read is high is to make y output the value from a. As soon as read goes low again y goes back to being an input (because you assign it the value z).

When read is LOW, I expect to output the value of b (which can be decremented or incremented by using minus or plus).

Since b is not an output, and you never use b to set any other wire or register, it's not clear how you expect that to happen.

Currently however, plus does not do anything

Are you sure? In your code, if plus is high at a rising edge of clk, then b will get the value y+1.

and read toggles y between 0xFFFF and 2

Are you sure the value is 0xFFFF and not 0xXXXX? Because when read is low, this code is not assigning any value at all to y. It sounds like your testbench is applying a pull-up or a weak high value to the bits of y.

\$\endgroup\$
  • \$\begingroup\$ I assume that b<=y makes y connected to b, as well as 'bz. \$\endgroup\$ – Jinkai Nov 30 '14 at 6:25
  • 1
    \$\begingroup\$ No. That only makes b get the value from y. It doesn't make y get the value from b. \$\endgroup\$ – The Photon Nov 30 '14 at 6:27
0
\$\begingroup\$

This is how I did it in the end

module tune #(parameter INIT=0, DELAY=19, BITS=16)(
    input clk,
    output reg [BITS-1:0] y = INIT,
    input enb,
    input add,
    input sub
);

reg [DELAY:0] count = 0;

always@(posedge clk) begin
    if (add^sub && count==0 && enb) y = add ? y+1:y-1;
    count <= count + 1;
end

endmodule
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.