Forum Discussion
Driving a module output with a reg?
Hello,
I'm trying to determine the best way to gain access to the output of a module which is simply a wire - who in it's own module is driven by a continuous assignment statement. The project is an implementation of the DES algorithm (courtesy OpenCores) with communication to and from the PC. Here is the code:
module receiving_test(sysclk, rxd, txd, LEDG, LEDR);
input sysclk, rxd;
output txd;
wire receiving_complete, isTransmitting;
output reg LEDG;
output reg LEDR;
reg begin_transmit;
reg tbyte;
wire rbyte;
parameter FIRST_BYTE = 0, GET_BYTES = 1, BEGIN_ENC = 2, CHECK_ENC_STATUS = 3, BEGIN_TRANSMISSION = 4, SEND_BYTES = 5;
reg state;
integer bytes_remaining;
reg sel;
reg plain_text;
reg cipher_text;
wire cipher_net;
uart uart1(
.clk(sysclk),
.rx(rxd),
.tx(txd),
.transmit(begin_transmit),
.tx_byte(tbyte),
.received(receiving_complete),
.rx_byte(rbyte),
.is_transmitting(isTransmitting)
);
des des1(
.clk(sysclk),
.key(56'h0),
.roundSel(sel),
.decrypt(1'b0),
.desIn(plain_text),
.desOut(cipher_net)
);
always @(posedge sysclk)
begin
cipher_text = cipher_net;
begin_transmit = 1'b0;
case(state)
FIRST_BYTE: begin
if(receiving_complete) begin
plain_text = rbyte;
plain_text = plain_text >> 8;
bytes_remaining = 7;
state = GET_BYTES;
end
end
GET_BYTES: begin
if(receiving_complete) begin
plain_text = rbyte;
bytes_remaining = bytes_remaining - 1;
if(bytes_remaining == 0) begin
state = BEGIN_ENC;
end else begin
plain_text = plain_text >> 8;
end
end
end
BEGIN_ENC: begin
sel = 4'b0;
state = CHECK_ENC_STATUS;
end
CHECK_ENC_STATUS: begin
sel = sel + 1;
if(sel == 15) begin
LEDG = cipher_text;
LEDR = cipher_text;
state = BEGIN_TRANSMISSION;
end
end
BEGIN_TRANSMISSION: begin
tbyte = cipher_text;
begin_transmit = 1'b1;
cipher_text = cipher_text >> 8;
bytes_remaining = 7;
state = SEND_BYTES;
end
SEND_BYTES: begin
if(!isTransmitting) begin
tbyte = cipher_text;
begin_transmit = 1'b1;
bytes_remaining = bytes_remaining - 1;
if(bytes_remaining == 0) begin
state = FIRST_BYTE;
end else begin
cipher_text = cipher_text >> 8;
end
end
end
endcase
end
endmodule
And here is the error I'm hoping to correct: Warning (10034): Output port "LEDG" at receiving_test.v(6) has no driver Warning (10034): Output port "LEDR" at receiving_test.v(7) has no driver .... among various others that I was able to determine after some research are consequences of these two. Basically, the output desOut from the DES module is not being properly driven. I'm aware that it is illegal to hook-up the output of an instantiated module directly to a 'reg', so I tried the work-around of: 1) first declaring a wire in the top-level module 2) Connecting this wire to the desOut output in the instantiation 3) Assigning the output of this wire to a reg at the posedge of the clock -- This didn't work. I need to be able to sample the value at desOut, but I'm unable to do so because it has no drive strength - and I'm not sure how to supply it with any! Any suggestions on this issue, or the code in general for that matter - are greatly appreciated! P.S. Each module has been tested separately, and the RS232 transmitter and receiver together. I'm quite sure that this should be mostly working if I can figure out this issue. P.P.S - I've also read in many Verilog references that in procedural blocks it is best practice to use non-blocking assignment. However, using these I was not getting the intended behavior. After looking at some state machine examples similar in nature to what I'm trying to achieve - I notices these were actually using blocking assignments. After trying this out, blocking assignments did indeed give me the functionality I was looking for. This seems to conflict - can anyone shed some light as to why this might be? Thanks! Kristin5 Replies
- Altera_Forum
Honored Contributor
--- Quote Start --- Warning (10034): Output port "LEDG" at receiving_test.v(6) has no driver Warning (10034): Output port "LEDR" at receiving_test.v(7) has no driver --- Quote End --- The warning means that the code assigning values to the LED ports is unreachable. It must be an unequivocal condition. In this case (sel == 16) is always false, because sel has a range of 0-15. - Altera_Forum
Honored Contributor
Whoops.. that should actually have been 15. I changed it for debugging and forgot to change it back.
With the condition set to if( sel == 15) the problem still persists. Can you see any other anamolies in the code? What exactly do you mean by uneqivocal condition? Thanks, Kristin - Altera_Forum
Honored Contributor
I would simulate this logic to see if it steps through the statemachine as expected. If I had to guess the integer 'bytes_remaining' can never be set to 0 and as a result that trickles down to the CHECK_ENC_STATUS never being reachable. That was just a wild stab in the dark though, I'm not really following what's going on in the state machine since it's coded in a style that I typically avoid.
By the way you should have reset conditions for your registers. - Altera_Forum
Honored Contributor
@BadOmen: Thanks for the reply.
Why is this typically a style that you avoid? I'm trying to learn best practices still. Also, why would the integer not be able to reach 0 - should I use registers for this value instead? Thanks, Kristin - Altera_Forum
Honored Contributor
My way might be a little confusing at first. I typically one-hot encode my statemachines.... and I don't write them as giant case statements either which throws people off who code statemachines the way they learned in school.
The way I code your sort of statemachine would be: - 3 bit counter (same state encoding) - counter enable driven by an assign statement that determines when to move to the next state - bunch of assign statements for all the outputs (or register enables depending on whether those outputs need to be captured by a register That only works for sequential state machines, for non sequential I typically one-hot encode them and build the state transistion logic manually. If the state machine becomes too big for one-hot encoding... well in my opinion that means you haven't though it through enough and should consider assembling smaller statemachines, and if that doesn't work then you probably have something that belongs in the software realm anyway (so Nios II would be an option). If you are wondering why I prefer this method it's mainly two reasons: 1) my coding style is to never put blocking operations in an always block, 2) I prefer to code without relying much on synthesis to optimize things for me.