Keybord interface design in Verilog - verilog

I am new to Verilog and I am trying to create one of my first programs which should display something when key on keybord is pressed. I'd like to use example code from Verilog coursebook, but I have some problems with pin assingment (I use DE2-70 from Altera).
Why I have input ReadKB; while there is nothing like this in module definition?
I know which pins should be assign to KBclk and KBdata. (PS2_KBCLK PIN_F24 PS/2 Clock and (PS2_KBDAT PIN_E24 PS/2 Data) What about ResetKB?
In the coursebook there is no explanation and I am really courious about it.
Code:
module KeyboardInterface(KBclk, KBdata, ResetKB, SYNclk, ScanRdy, ScanCode, KeyReleased);
input KBclk;
input KBdata;
input ResetKB;
input ReadKB;
input SYNclk;
output ScanRdy;
output ScanCode;
output KeyReleased;
//Generate an internal synchronized clock
reg Clock;
always #(posedge SYNclk) Clock = KBclk;
reg[3:0] BitCount;
reg StartBitDetected, ScanRdy;
reg[7:0] ScanCode;
//Count the number of serial bits and collect data into ScanCode
always #(posedge Clock) begin
if(ResetKB) begin
BitCount=0; StartBitDetected =0;
end else begin
if(KBdata == 0 && StartBitDetected == 0) begin
StartBitDetected=1;
ScanRdy = 0;
end else if (StartBitDetected) begin
if(BitCount < 8) begin
BitCount = BitCount + 1;
ScanCode = {KBdata, ScanCode[7:1]};
end else begin
StartBitDetected = 0;
BitCount = 0;
ScanRdy = 1;
end
end
end
end
reg [1:0] CompletionState;
wire KeyReleased;
//keep track of the state of Scan Codes outputted
always #(posedge SYNclk) begin
if(ResetKB) CompletionState = 0;
else case(CompletionState)
0: if(ScanCode == 8'h70 && ScanRdy == 1) CompletionState =1;
else CompletionState =0;
1: if(ScanRdy == 1) CompletionState =1;
else CompletionState =2;
2: if(ScanRdy == 0) CompletionState = 2;
else CompletionState = 0;
3: CompletionState = 0;
endcase
end
assign KeyReleased = CompletionState == 3 ? 1 : 0;
endmodule
Thank you!

That looks like a typo, just go ahead and add the missing wire to the module definition.
There's probably not actually a 'reset' coming from your keyboard if that's what you're asking. I'd just tie it to some pushbutton on the Altera if it is available.

It is just a high-level reset signal. You can just connect it with a push button, then you can use the push button to reset the reg signals, bitcount and startbitdetect.
But one crucial thing you should note is that reg signals can not use "=" inside the always section, it should be "<=". This is the difference between blocking and non-blocking assignment that you should pay more attentions on. Good luck.:-)

Related

reg instantiate with 1 in verilog

I'm making a simple project with leds blinking every second. Led 1 and 3 blink alternating to led 2 and 4. I've written the following Verilog code:
module leds_blinking(input i_Clk,
output o_LED_1,
output o_LED_2,
output o_LED_3,
output o_LED_4);
parameter c_CYCLESINSECOND = 50_000_000;
reg r_LED_1 = 1;
reg r_LED_2 = 0;
reg r_LED_3 = 1;
reg r_LED_4 = 0;
reg [32:0] r_Count = 0;
always #(posedge i_Clk)
begin
if (r_Count < c_CYCLESINSECOND)
r_Count <= r_Count + 1;
else if (r_Count == c_CYCLESINSECOND)
begin
r_LED_1 <= ~r_LED_1;
r_LED_2 <= ~r_LED_2;
r_LED_3 <= ~r_LED_3;
r_LED_4 <= ~r_LED_4;
r_Count <= 0;
end
else
r_Count <= 0;
end
assign o_LED_1 = r_LED_1;
assign o_LED_2 = r_LED_2;
assign o_LED_3 = r_LED_3;
assign o_LED_4 = r_LED_4;
endmodule
All LEDs are active at the same time, though I instantiated 1,3 other than 2,4.
I’m assuming you are synthesizing and not running simulation on the RTL first. Synthesizer that target for ASIC typically ignore default values and initial blocks. Synthesizer that target for FPGA often do. Not knowing which synthesizer you are using it is hard to guess your root causes issue.
However, you can simplify your code and solve your problem by using one registers instead of four. Notice how the o_LED_# are driven.
always #(posedge i_Clk)
begin
if (r_Count < c_CYCLESINSECOND)
r_Count <= r_Count + 1;
else
begin
r_LED <= ~r_LED;
r_Count <= 0;
end
end
assign o_LED_1 = r_LED;
assign o_LED_2 = ~r_LED;
assign o_LED_3 = r_LED;
assign o_LED_4 = ~r_LED;

I2C slave module in Verilog does not acknowledge

I wrote this I2C slave module in Verilog:
module I2CSlave(
input iSCL,
input iI2C_CLK,
inout bSDA,
output reg [7:0] odata,
output reg oread,
output wire oactive
);
reg incycle = 1'b0;
reg pSDA;
reg pSCL;
always #(posedge iI2C_CLK) begin
if ((pSCL) && (iSCL) && (pSDA) && (~bSDA)) begin
incycle <= 1;
end
if ((pSCL) && (iSCL) && (~pSDA) && (bSDA)) begin
incycle <= 0;
end
pSDA <= bSDA;
pSCL <= iSCL;
end
assign oactive = incycle;
localparam STATE_IDLE = 0;
localparam STATE_ADDR = 1;
localparam STATE_RW = 2;
localparam STATE_ACK = 3;
localparam STATE_DATA = 4;
localparam STATE_ACK2 = 5;
reg [7:0] i = 0;
reg [7:0] state = STATE_IDLE;
reg [6:0] addr = 7'h03;
reg addr_match = 1;
reg rw;
reg lSDA;
always #(posedge iSCL) lSDA <= bSDA;
assign bSDA = ((state == STATE_ACK) || (state == STATE_ACK2)) ? 0 : 1'bz;
assign oread = (state == STATE_ACK2);
assign ostate = i;
always #(negedge iSCL or negedge incycle) begin
if (~incycle) begin
state <= STATE_IDLE;
addr_match <= 1;
end
else if (addr_match) begin
case (state)
STATE_IDLE: begin
state <= STATE_ADDR;
i <= 7;
end
STATE_ADDR: begin
if (addr[i-1] != lSDA) addr_match <= 0;
if (i == 1) begin
state <= STATE_RW;
i <= i - 1;
end
else i <= i - 1;
end
STATE_RW: begin
rw <= lSDA;
state <= STATE_ACK;
end
STATE_ACK: begin
state <= STATE_DATA;
i = 7;
end
STATE_DATA : begin
odata[i] <= lSDA;
if (i == 0) state <= STATE_ACK2;
else i <= i - 1;
end
STATE_ACK2: begin
state <= STATE_DATA;
i = 7;
end
endcase
end
end
endmodule
As of now it should just read the data sent by master. It seems to work well in simulation, but when I upload it into the FPGA, sometimes everything is OK, however sometimes it does not acknowledge the data sent by master and it just seems to ignore them. I am newbie in Verilog, so I hope, this is not a silly question.
One possible cause for random fails while running on real hardware is that you didn't synchronize inputs.
You are sampling slowly changing signals (i2c bus will have a long slopes) that are truly asynchronous to your design's clock. Depending on your luck, you will have random violations for setup/hold times of your fpga's d-flops, which results in metastability issues. The same value in the register might be treated differently in multiple parts of the chip. That will wreak havoc in your i2c slave's logic.
You must synchronize asynchronous inputs, in the simplest case passing it through a couple of registers before feeding it to the module's fsm.
You have several issues with your code which could cause mismatch in behavior in simulation and synthesis. For example, the following is not synthesizable and is ignored by synthesis tools. So, your initial state would be different. Check your logs for warnings. Do not use declaration assignments for regs. (ok for wires).
reg [7:0] i = 0;
reg [7:0] state = STATE_IDLE;
reg [6:0] addr = 7'h03;
reg addr_match = 1;
The above means that you initialization does not work.
You messed up blocking and non-blocking assignments in the state machine. Make sure that you use nbas in all places where 'i = 7'. it should be
i <= 7;
And make sure that you test enough initialization and different conditions in simulation.

how to properly connect receiver, sender and top and make them dependent from each other - RS232

I've got a simple project which requires me to write a code for RS232 receiver and sender, then put them together and, finally, test if it works properly. I've prepared code for both sender and receiver (and also connecting block - top). My problem is that I don't know how to connect them, so they could work with each other properly.
The main issue is that I can't "transfer" data from data_o to data_i because of the fact that one is reg and second - wire. I wouldn't like to use inout for these purposes. I can't figure out any possible modifications to make it work.
Another issue is putting some flags that could kind of follow idea like this: if receiving -> not sending, if sending -> not receiving.
Here's my code:
top.v
`timescale 1ns / 1ps
module top (
clk_i,
rst_i,
RXD_i,
data_i,
TXD_o,
data_o
);
input clk_i;
input rst_i;
input RXD_i;
output TXD_o;
//the problem is here, can't data_i <= data_o because output is reg
input [7:0] data_i;
output [7:0] data_o;
receiver r1(clk_i, RXD_i, data_o);
sender s1(clk_i, data_i, TXD_o);
endmodule
receiver.v
`timescale 1ns / 1ps
module receiver (
clk_i,
RXD_i,
data_o
);
//inputs and outputs
input clk_i;
input RXD_i;
output reg [7:0] data_o;
//counter values
parameter received_bit_period = 5208;
parameter half_received_bit_period = 2604;
//state definitions
parameter ready = 2'b00;
parameter start_bit = 2'b01;
parameter data_bits = 2'b10;
parameter stop_bit = 2'b11;
//operational regs
reg [12:0] counter = 0; //9765.625Hz
reg [7:0] received_data = 8'b00000000;
reg [3:0] data_bit_count = 0;
reg [1:0] state = ready;
//latching part
reg internal_RXD;
always #(posedge clk_i) //latch RXD_i value to internal_RXD
begin
internal_RXD = RXD_i;
end
always #(clk_i) //receiving process
begin
case (state)
ready :
begin
if (internal_RXD == 0)
begin
state <= start_bit;
counter <= counter + 1;
end
else
begin
state <= ready;
counter <= 0;
data_bit_count <= 0;
end
end
start_bit :
begin
if (counter == half_received_bit_period)
begin
if (internal_RXD == 0)
begin
state <= data_bits;
counter <= 0;
end
end
else
begin
state <= start_bit;
counter <= counter + 1;
end
end
data_bits :
begin
if (counter == received_bit_period)
begin
received_data[data_bit_count] <= internal_RXD;
data_bit_count <= data_bit_count + 1;
counter <= 0;
if (data_bit_count == 8)
state <= stop_bit;
end
else
counter <= counter + 1;
end
stop_bit:
begin
counter <= counter + 1;
if (counter == received_bit_period)
begin
state <= ready;
data_o <= received_data;
end
end
endcase
end
endmodule
sender.v
`timescale 1ns / 1ps
module sender (
clk_i,
data_i,
TXD_o
);
//inputs and outputs
input clk_i;
input [7:0] data_i;
output reg TXD_o;
//counter values
parameter received_bit_period = 5208;
parameter half_received_bit_period = 2604;
//state definitions
parameter ready = 1'b0;
parameter data_bits = 1'b1;
//operational regs
reg [12:0] counter = 0; //9765.625Hz
reg [9:0] framed_data = 0;
reg [3:0] data_bit_count = 0;
reg state = ready;
always #(posedge clk_i) //sending process
begin
case (state)
ready :
begin // flag needed?
state <= data_bits;
TXD_o <= 1;
framed_data[0] <= 1'b0;
framed_data[8:1] <= data_i;
framed_data[9] <= 1'b1;
counter <= 0;
end
data_bits :
begin
counter <= counter + 1;
if (data_bit_count == 10)
begin // flag needed?
state <= ready;
data_bit_count <= 0;
TXD_o <= 1;
end
else
begin
if (counter == received_bit_period)
begin
data_bit_count <= data_bit_count + 1;
end
TXD_o <= framed_data[data_bit_count];
end
end
endcase
end
endmodule
You don't!
In all CPU's and FPGA nowadays the read and write data path are separate buses. You will find that also with all CPU cores. Have a look at AXI or AHB bus protocols from ARM.
What is more worrying is the way you have implemented your functions. You would at least need some 'data valid' signal for the transmitter to know when there is valid data to transmit and for the receive when valid data has arrived.
Even that is not enough because for the TX the connecting logic would need to know when the data has been send and the next byte can go out.
You need to make a (preferably standard) CPU interface which talks to your UART. (For beginner I would not use AXI.)
As to your flags: they would come from within the CPU interface.
Last: a UART should be capable of transmitting and receiving at the same time.

verilog asynchronous FIFO Wizard

How do you use the read enable to properly output a signal on a pin? I am using a ZyBo board and used a the FIFO Generator Wizard. I need an asynchronous, continuous writing to a FIFO and reading from the FIFO. This is why I need a write_enable signal and read_enable signal. However, I cannot read from the FIFO. I check to make sure the FIFO isn't empty and that read_enable is asserted. I read from the FIFO by serializing a 32bit word onto a data pin. (It alternates from serializing onto pin I and pin Q). How can I make sure I am reading from the FIFO and outputting the serialized data onto a pin? The following is my code:
// Wires and registers related to data capturing
wire capture_clk;
reg [31:0] capture_data;
wire capture_en;
reg [4:0] slowdown;
wire capture_full;
reg capture_open;
reg capture_open_cross;
reg capture_has_been_full;
reg capture_has_been_nonfull;
reg has_been_full_cross;
reg has_been_full;
// Data capture section
// ====================
always #(posedge capture_clk)
begin
if (capture_en)
capture_data <= user_w_write_32_data; // Data source being read from a file
// The slowdown register limits the data pace to 1/32 the bus_clk
// when capture_clk = bus_clk. This is necessary, because the
// core in the evaluation kit is configured for simplicity, and
// not for performance. Sustained data rates of 200 MB/sec are
// easily reached with performance-oriented setting.
// The slowdown register has no function in a real-life application.
slowdown <= slowdown + 1;
// capture_has_been_full remembers that the FIFO has been full
// until the file is closed. capture_has_been_nonfull prevents
// capture_has_been_full to respond to the initial full condition
// every FIFO displays on reset.
if (!capture_full)
capture_has_been_nonfull <= 1;
else if (!capture_open)
capture_has_been_nonfull <= 0;
if (capture_full && capture_has_been_nonfull)
capture_has_been_full <= 1;
else if (!capture_open)
capture_has_been_full <= 0;
end
// The dependency on slowdown is only for bogus data
assign capture_en = capture_open && !capture_full &&
!capture_has_been_full &&
(slowdown == 0);
// Clock crossing logic: bus_clk -> capture_clk
always #(posedge capture_clk)
begin
capture_open_cross <= user_r_read_32_open;
capture_open <= capture_open_cross;
end
// Clock crossing logic: capture_clk -> bus_clk
always #(posedge bus_clk)
begin
has_been_full_cross <= capture_has_been_full;
has_been_full <= has_been_full_cross;
end
// The user_r_read_32_eof signal is required to go from '0' to '1' only on
// a clock cycle following an asserted read enable, according to Xillybus'
// core API. This is assured, since it's a logical AND between
// user_r_read_32_empty and has_been_full. has_been_full goes high when the
// FIFO is full, so it's guaranteed that user_r_read_32_empty is low when
// that happens. On the other hand, user_r_read_32_empty is a FIFO's empty
// signal, which naturally meets the requirement.
assign user_r_read_32_eof = user_r_read_32_empty && has_been_full;
assign user_w_write_32_full = 0;
// The data capture clock here is bus_clk for simplicity, but clock domain
// crossing is done properly, so capture_clk can be an independent clock
// without any other changes.
assign capture_clk = bus_clk;
async_fifo_32x512 fifo_32 //FIFO created using Xilinx FIFO Generator Wizard
(
.rst(!user_r_read_32_open),
.wr_clk(capture_clk),
.rd_clk(bus_clk),
.din(capture_data),
.wr_en(capture_en),
.rd_en(user_r_read_32_rden),
.dout(user_r_read_32_data),
.full(capture_full),
.empty(user_r_read_32_empty)
);
reg Q_en = 1'b0; //starting value is 0 because first 32bit is I
reg [31:0] data_outI = 32'd0;
reg [31:0] data_outQ = 32'd0;
reg I = 1'b0;
reg Q = 1'b0;
reg counter_32_shift = 6'b000000;
reg temp = 1'b0;
always #(posedge bus_clk) begin
if(user_r_read_32_empty == 1'b0 && user_r_read_32_rden == 1'b1)begin //if something in FIFO
if(Q_en == 1'b0) begin //output onto pin I
if(counter_32_shift == 6'b000000) begin
data_outI <= user_r_read_32_data;
end else if(counter_32_shift != 5'd32) begin
I <= data_outI[0];
data_outI <= (data_outI >> 1);
Q <= data_outQ[0];
data_outQ <= (data_outQ >> 1);
counter_32_shift <= counter_32_shift + 1'b1;
end else begin //counter_32_shift == 32
I <= data_outI[0];
data_outI <= (data_outI >> 1);
Q <= data_outQ[0];
data_outQ <= (data_outQ >> 1);
counter_32_shift <= 6'd0;
Q_en <= ~Q_en;
end
end else if(Q_en == 1'b1) begin //Output onto pin Q
if(counter_32_shift == 6'd0) begin
data_outQ <= user_r_read_32_data;
end else if(counter_32_shift != 6'd32) begin
I <= data_outI[0];
data_outI <= (data_outI >> 1);
Q <= data_outQ[0];
data_outQ <= (data_outQ >> 1);
counter_32_shift <= counter_32_shift + 1'b1;
end else begin //counter_32_shift == 32
I = data_outI[0];
data_outI <= (data_outI >> 1);
Q = data_outQ[0];
data_outQ <= (data_outQ >> 1);
counter_32_shift <= 6'd0;
Q_en <= ~Q_en;
end
end// end Q_en compare
end //end check if FIFO empty
end //end always
Thanks in advance for all the help
You need to design a bit better the way you write your clocked logic.
For example, in your code, you only write to I and Q if the fifo is not empty, which is not correct.
You need a module which:
Takes in a 32-bit value from the fifo, stores it, and then serializes it out to a pin over 32 cycles.
Once a value has been read in from the fifo, it needs to keep serializing regardless of whether or not the fifo is empty (you only care about the state of the fifo when you're pulling in a new 32-bit value).
Only accepts a new value when it is not currently doing serialization.
The design looks to be making progress since your last question, but you haven't got the logic right yet. Try using a waveform debugger to understand better why it's not working the way you expect.

Verilog design: Where should my counter live?

I am coding in Verilog a typical count-to-n-then-reset-to-0 counter. My module has the logic to increment and reset the counter.
My issue is that I don't know where the counter itself should be defined.
I could pass the counter (as inout?) to the module. That's ok, but the counter still has to be defined somewhere so it this doesn't do me any good.
Nothing else except this module should touch the counter, so I'd like to have the counter created within this module, and not passed in or out.
Is this reasonably standard, and if so, will someone point to a reference please on how to instantiate the counter?
(I'm on day 2 of Verilog, so be afraid, heh)
EDIT - here's the code. As far as I can tell, it works. I haven't implemented DIR == REVERSE yet.
Couple of interesting gotchas. The (now commented out) STEPPER=0 line was causing an error in a schematic; it thought that STEPPER was tied to ground as well as other logic.
Also, I use = instead of <= in some places involving counter - I was getting timing problems (I suppose.) The procedural assignment removed (hid?) the problem.
module cam(
input [7:0] DIVISOR,
input DIR,
input SPINDLE,
output reg STEPPER
);
parameter FORWARD = 1'b1;
parameter REVERSE = !FORWARD;
reg[7:0] counter = 0;
always #(posedge SPINDLE) begin
// STEPPER = 0;
if (DIR == FORWARD) begin
counter = counter + 1;
if (counter == DIVISOR) counter = 0;
end
else begin
// counter <= counter - 1;
// if (counter == (-1)) counter <= DIVISOR;
end
end
always #(negedge SPINDLE) begin
STEPPER = (counter == 0) ? 1 : 0;
end
endmodule
Should just be defined as a register within the module. Here's an example from some of my code.
module trigger(clk, rxReady, rxData, txBusy, txStart, txData);
input clk;
input [7:0] rxData;
input rxReady;
input txBusy;
output reg txStart;
output reg[7:0] txData;
integer count81; // Number of cells received over serial (start solving after 81)
reg[8:0] data[0:8][0:8];
integer state;
always #(posedge clk) begin
case (state)
read:
if (rxReady) begin
data[count81 % 9][count81 / 9] = rxData ? 1<<(rxData-1) : -1;
if (count81 < 80) count81 <= count81 + 1;
else begin
count81 <= 0;
state <= solving;
end
end
etc....
endcase
end
endmodule
Congrats on getting out of the Java world for the time being. FPGAs are the only thing that seems exciting anymore.

Resources