Verilog注册阵列



在1D reg数组中循环时遇到一些问题。

最终我正在努力完成以下任务。

  1. 在"侦听"状态下,rx值填充一个读取缓冲区(4个8位字符),以存储控制台中键入的字符,并通过将tx_data设置为最后一个字符来回显该字符(此操作有效)

  2. 当按下回车键时,状态切换到"读取",在每次迭代中将tx_data设置为读取缓冲区,直到达到第4个字符,此时状态重置为空闲。(这不起作用)

我进入读取状态;然而,计数器并没有按预期工作。

任何帮助都将不胜感激。

module receiver (
input clk,
input rst,
output reg [7:0] tx_data,
output reg new_tx_data,
input tx_busy,
input [7:0] rx_data,
input new_rx_data
);
localparam idle = 4'h0 ,listen = 4'h1 ,read = 4'h2, write = 4'h3; 
reg [3:0] state = idle;
reg [7:0] readbuff[3:0];
integer buffdex;
always @* begin
end

always @(posedge clk) begin
new_tx_data = 1'b0;
case (state) 
idle: begin 
if(new_rx_data) begin
state<=listen;
end
end
listen: begin
new_tx_data = 1'b1;
readbuff[buffdex] = rx_data;
tx_data = readbuff[buffdex];
//tx_data = buffdex;
buffdex = buffdex + 1';
if(rx_data == 8'h0D) begin
tx_data = "n";
buffdex = 0;
state <= read;
end else begin
state<=idle;
end
end
read: begin
new_tx_data = 1'b1;
tx_data = readbuff[buffdex];
buffdex = buffdex + 1;
if (buffdex == 3) begin
state <= idle;
end
//tx_data = state;
end
endcase
end
endmodule

很抱歉使用"答案"功能而不是注释,但我还没有足够的分数。这是一个"评论"。既然你想要any help,我希望这个合适。

1) 您的代码在功能和可读性方面都需要一些改进(空的组合块,将BA与NBA混合->将组合与顺序逻辑混合,重置输入但没有重置逻辑,注释的逻辑线,FSM上的锁存)。

考虑根据一些良好的编码实践重写它,例如。http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf

您还存在类似buffdex = buffdex + 1'buffdex = buffdex + 1的不一致性。(因此没有精辟的汇编)。

2) 你能为这个模块提供一个测试台吗?你有没有试过用频闪信号来检查它们的值?buffdexread状态下是否递增?if语句是否可访问?

3) 由于这不是Mojo的第一个问题(似乎正在开发中),您可以考虑免费https://www.edaplayground.com/用于测试和编译/语法检查。

所以我阅读了这篇论文(以及其他各种IEEE说明),最终得到了一个工作版本。下面是代码。和以前一样,我对如何使代码更高效或更实用持开放态度。我认为读取缓冲区是一个很大的锁存器,但不确定如何修复它

module receiver (
//inputs
input clk,
input rst,
input tx_busy,
input [7:0] rx_data,
input new_rx_data,
//outputs
output reg [7:0] tx_data,
output reg new_tx_data,
output reg [0:4] LED
);

//local parameters
localparam IDLE = 2'b00 , LISTEN = 2'b01 ,NEWLINE = 2'b10, READ = 2'b11;

//fsm state reg and readbuff reg
reg [1:0] stated, stateq;
reg [3:0] cntrd,cntrq;
reg [7:0] readbuff [15:0];
reg nl;
//on clock edge set flip-flop  - non-blocking assignments
always @(posedge clk ) begin
if(rst) begin
stateq <= IDLE; 
cntrq<=4'b0000;
end else begin
//update the state and readbuff index values to be current.
stateq <= stated;
cntrq <=cntrd;
end
end
//sequential and combinational blocking assignments
always @(*) begin
//set default states to avoid latches.
stated = stateq;
cntrd = cntrq; 
LED = cntrq;
//set output defaults
tx_data = 8'hxx;
new_tx_data = 1'b0;
case (stateq) 
IDLE: begin
//move to listen state
cntrd=4'b0;
stated = stateq + 1'b1;
end
LISTEN: begin
if(new_rx_data) begin
//set readbuffer[indx] to the rx data
readbuff[cntrq] = rx_data;
new_tx_data = 1'b1;
tx_data = readbuff[cntrq];
cntrd = cntrq + 1'b1;
//if enter is pressed change states, otherwise, echo and increase the read buffer.
if(rx_data == "r" || rx_data == "n") begin
stated = stateq + 1'b1;
cntrd=4'b0000;
end
end
end
NEWLINE: begin  
if(!tx_busy) begin
new_tx_data = 1'b1;
tx_data = 8'h0A;
nl = 1'b1;
stated = stateq + 1'b1;
end
end
READ: begin
//check the value of cntrq for the enter statement 
if(readbuff[cntrq] == "r" || readbuff[cntrq] == "n" ) begin
stated = IDLE;
//otherwise write out the value of the readbuff - tx busy should sync to avr clock
end else begin    
if (!tx_busy) begin
new_tx_data = 1'b1;
tx_data = readbuff[cntrq];
cntrd = cntrq + 1'b1;
end  
end
end    
endcase
end
endmodule

最新更新