在循环访问1D reg数组时遇到一些麻烦。
最终我试图完成以下任务。
在“Listen”状态下,rx_values填充一个读缓冲区(4个8位字符)来存储在控制台中输入的字符,并通过将tx_data设置为最后一个字符来回显该字符(这有效)
当按下回车键时,状态切换到“读取”,每次迭代将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
答案 0 :(得分:1)
很抱歉使用&#34;回答&#34;功能而不是评论,但我还没有足够的分数。这是一个&#34;评论&#34;。既然你想要any help
,我希望这适合。
1)您的代码在功能和可读性方面都需要一些改进(空组合块,将BA与NBA混合 - &gt;混合组合与顺序逻辑,复位输入但没有复位逻辑,注释逻辑线,FSM上的锁存器)。 / p>
考虑根据一些好的编码实践重写它,例如http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf
您还会遇到buffdex = buffdex + 1'
和buffdex = buffdex + 1
等不一致的问题。 (因而没有精辟的编译)。
2)您能为此模块提供测试平台吗?您是否尝试过频闪信号来检查它们的值? buffdex
状态read
会增加吗? if
语句是否可以访问?
3)由于这不是Mojo的第一个问题(似乎正在开发中),您可以考虑免费https://www.edaplayground.com/进行测试和编译/语法检查。
答案 1 :(得分:0)
所以我读了这篇论文(以及其他各种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