I have never used Verilog (well I am used to VerilogA), and back during my undergraduate days HDL was VHDL for me. The industry at large seems to prefer Verilog, and I decided to catch up on the basics before I head out to Leuven.
Looking for problem, I came across a slide from NCSU. The problem was:
//There are 9 bytes of data.
//The first byte is the packet identifier. 2'h55 indicates a valid data packet containing 7 data bytes and // one checksum byte is following.
//The next seven bytes are data bytes.
//The last byte is the checksum
//If the sum of the 7 data bytes truncated to 8 bits do not match the checksum byte,
//the error signal is to be asserted and kept high until the next valid data byte starts appearing
This was the code I wrote:
`timescale 1ns / 1ps
//There are 9 bytes of data.
//The first byte is the packet identifier. 2'h55 indicates a valid data packet is follwoing
//The next seven bytes are data bytes.
//The last byte is the checksum
//If the sum of the 7 data bytes truncated to 8 bits do not match the checksum byte,
//the error signal is to be asserted and kept high until the next valid data byte starts appearing
module check_sum(
input clk,
input reset_bar,
input [7:0] data,
output error
);
reg [7:0]internal_sum;
reg [2:0]state_vec;
reg [3:0]byte_count;
reg error_state;
always @(posedge clk or negedge reset_bar) begin
if (~reset_bar) begin
state_vec=3'b000;
error_state=1'b0;
internal_sum=0;
byte_count=0;
end
else if (state_vec == 3'b000) begin
//this means it is waiting for new data frame
//check whether the data is 2'h55 or not.
internal_sum=0; //since we are wiating for a new data frame, sum is set to zero
if (data==8'b01010101)begin
state_vec=3'b001; //1 indicates that it is ready to receive the data
error_state=0;
end
else begin
state_vec=3'b100; //4 indicates that it is in invalid data frame and should be ignored
end
byte_count=0;
end
else if (state_vec==3'b001) begin
//increment byte counter
byte_count=byte_count+1;
internal_sum=internal_sum+data;
if (byte_count==4'b0111) begin
//all seven bytes have been received. the next byte will be the checksum
state_vec=3'b010; //a value of 2 for the state vector indicates that it is ready for checksum cehck.
end
end
else if (state_vec==3'b010) begin
//reset the byte count
byte_count=4'b0000;
if (internal_sum != data)
error_state=1'b1;
else
error_state=1'b0;
state_vec=3'b000;
end
else if (state_vec==3'b100) begin
//nothing to do really other than increment the byte counter
byte_count=byte_count+1;
if (byte_count==4'b1000)
//received all the 7 bytes of data plus one checksum byte
state_vec=3'b000;
else
state_vec=3'b100;
end
end
assign error=error_state?1'b1:1'b0;
endmodule
Looking for problem, I came across a slide from NCSU. The problem was:
//There are 9 bytes of data.
//The first byte is the packet identifier. 2'h55 indicates a valid data packet containing 7 data bytes and // one checksum byte is following.
//The next seven bytes are data bytes.
//The last byte is the checksum
//If the sum of the 7 data bytes truncated to 8 bits do not match the checksum byte,
//the error signal is to be asserted and kept high until the next valid data byte starts appearing
This was the code I wrote:
`timescale 1ns / 1ps
//There are 9 bytes of data.
//The first byte is the packet identifier. 2'h55 indicates a valid data packet is follwoing
//The next seven bytes are data bytes.
//The last byte is the checksum
//If the sum of the 7 data bytes truncated to 8 bits do not match the checksum byte,
//the error signal is to be asserted and kept high until the next valid data byte starts appearing
module check_sum(
input clk,
input reset_bar,
input [7:0] data,
output error
);
reg [7:0]internal_sum;
reg [2:0]state_vec;
reg [3:0]byte_count;
reg error_state;
always @(posedge clk or negedge reset_bar) begin
if (~reset_bar) begin
state_vec=3'b000;
error_state=1'b0;
internal_sum=0;
byte_count=0;
end
else if (state_vec == 3'b000) begin
//this means it is waiting for new data frame
//check whether the data is 2'h55 or not.
internal_sum=0; //since we are wiating for a new data frame, sum is set to zero
if (data==8'b01010101)begin
state_vec=3'b001; //1 indicates that it is ready to receive the data
error_state=0;
end
else begin
state_vec=3'b100; //4 indicates that it is in invalid data frame and should be ignored
end
byte_count=0;
end
else if (state_vec==3'b001) begin
//increment byte counter
byte_count=byte_count+1;
internal_sum=internal_sum+data;
if (byte_count==4'b0111) begin
//all seven bytes have been received. the next byte will be the checksum
state_vec=3'b010; //a value of 2 for the state vector indicates that it is ready for checksum cehck.
end
end
else if (state_vec==3'b010) begin
//reset the byte count
byte_count=4'b0000;
if (internal_sum != data)
error_state=1'b1;
else
error_state=1'b0;
state_vec=3'b000;
end
else if (state_vec==3'b100) begin
//nothing to do really other than increment the byte counter
byte_count=byte_count+1;
if (byte_count==4'b1000)
//received all the 7 bytes of data plus one checksum byte
state_vec=3'b000;
else
state_vec=3'b100;
end
end
assign error=error_state?1'b1:1'b0;
endmodule
The test bench that I used was:
`timescale 1ns / 1ps
module test_check_sum;
reg [7:0]data;
reg reset_bar;
reg clk;
wire error;
integer i;
integer k;
reg [7:0]data_sum;
check_sum DUT (clk,reset_bar,data,error);
initial begin
reset_bar=1'b1;
data_sum=0;
#10
reset_bar=1'b0;
#10
reset_bar=1'b1;
#5
//we will run the simulation for 5 different data packets.
for(i=0;i<5;i=i+1) begin
data_sum=0;
//data=8'h55; //to indicate the start of the packet
if (i==1)
data=8'h56;
else
data=8'h55;
#40
for(k=1;k<=7;k=k+1) begin
data=$urandom_range(0,255);
data_sum=data_sum+data;
#40;
end
data=data_sum+1;
#40;
end
end
always begin
clk=1'b0;
#45
clk=1'b1;
forever begin
#20
clk=~clk;
end
end
endmodule
module test_check_sum;
reg [7:0]data;
reg reset_bar;
reg clk;
wire error;
integer i;
integer k;
reg [7:0]data_sum;
check_sum DUT (clk,reset_bar,data,error);
initial begin
reset_bar=1'b1;
data_sum=0;
#10
reset_bar=1'b0;
#10
reset_bar=1'b1;
#5
//we will run the simulation for 5 different data packets.
for(i=0;i<5;i=i+1) begin
data_sum=0;
//data=8'h55; //to indicate the start of the packet
if (i==1)
data=8'h56;
else
data=8'h55;
#40
for(k=1;k<=7;k=k+1) begin
data=$urandom_range(0,255);
data_sum=data_sum+data;
#40;
end
data=data_sum+1;
#40;
end
end
always begin
clk=1'b0;
#45
clk=1'b1;
forever begin
#20
clk=~clk;
end
end
endmodule
Here is a snap of the waveform:
did you fix this issue
ReplyDelete