Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Koen Martens
gmcpu8
Commits
8cb95d13
Commit
8cb95d13
authored
Aug 26, 2019
by
Koen Martens
Browse files
uart: implement receive logic in top-level module
parent
54273110
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/verilog/common/testbench_tasks/simulate_sin.v
0 → 100644
View file @
8cb95d13
task
simulate_sin
(
input
[
TB_DATA_WIDTH
-
1
:
0
]
data
,
input
string
message
=
""
,
input
integer
clk_divider
=
2
,
input
stop_bit
=
1'b1
,
input
integer
stop_clk_count
=
clk_divider
*
16
);
integer
bit_index
;
string
formatted
;
begin
tb_sin
=
1'b0
;
// start bit
repeat
(
clk_divider
*
16
)
@
(
posedge
clk
);
bit_index
=
0
;
repeat
(
TB_DATA_WIDTH
)
begin
tb_sin
=
data
[
bit_index
];
repeat
(
clk_divider
*
16
)
@
(
posedge
clk
);
bit_index
+=
1
;
end
tb_sin
=
stop_bit
;
// stop bit
repeat
(
stop_clk_count
)
@
(
posedge
clk
);
end
endtask
src/verilog/wishbone/uart/receive.v
View file @
8cb95d13
...
...
@@ -90,6 +90,7 @@ module receive #(
end
else
begin
framing_error_o
=
1'b1
;
state
<=
STATE_DATA
;
data_bit
<=
1
;
end
end
end
else
begin
...
...
src/verilog/wishbone/uart/receive_tb.v
View file @
8cb95d13
...
...
@@ -50,29 +50,7 @@ module receive_tb();
`include
"common/testbench_tasks/tb_assert.v"
task
simulate_sin
(
input
[
TB_DATA_WIDTH
-
1
:
0
]
data
,
input
string
message
=
""
,
input
stop_bit
=
1'b1
,
input
integer
stop_clk_count
=
32
);
integer
bit_index
;
string
formatted
;
begin
tb_sin
=
1'b0
;
// start bit
repeat
(
32
)
@
(
posedge
clk
);
bit_index
=
0
;
repeat
(
TB_DATA_WIDTH
)
begin
tb_sin
=
data
[
bit_index
];
repeat
(
32
)
@
(
posedge
clk
);
bit_index
+=
1
;
end
tb_sin
=
stop_bit
;
// stop bit
repeat
(
stop_clk_count
)
@
(
posedge
clk
);
end
endtask
`include
"common/testbench_tasks/simulate_sin.v"
integer
counter
;
...
...
@@ -103,7 +81,7 @@ module receive_tb();
repeat
(
32
)
@
(
posedge
clk
);
simulate_sin
(
8'b01001011
,
"framing error"
,
1'b0
,
16
);
simulate_sin
(
8'b01001011
,
"framing error"
,
2
,
1'b0
,
16
);
tb_assert
(
tb_framing_error_o
===
1'b1
,
"framing_error_o asserted after framing error"
);
repeat
(
16
)
begin
...
...
src/verilog/wishbone/uart/uart.v
View file @
8cb95d13
`include
"wishbone/uart/transmit.v"
`include
"wishbone/uart/receive.v"
module
uart
#(
parameter
DATA_WIDTH
=
8
,
...
...
@@ -57,44 +58,80 @@ module uart #(
.
data_ready_i
(
~
LSR_THRE
)
);
wire
[
DATA_WIDTH
-
1
:
0
]
receiver_data
;
reg
receiver_data_latched
;
wire
receiver_data_ready
;
wire
receiver_framing_error
;
receive
#(
.
DATA_WIDTH
(
DATA_WIDTH
),
.
DIVISOR_WIDTH
(
16
)
)
receiver
(
.
clk_i
(
clk_i
),
.
rst_i
(
rst_i
),
.
data_o
(
receiver_data
),
.
clk_divisor_i
(
{
DLM
,
DLL
}
),
.
sin
(
sin
),
.
data_latched_i
(
receiver_data_latched
),
.
data_ready_o
(
receiver_data_ready
),
.
framing_error_o
(
receiver_framing_error
)
);
always
@
(
posedge
clk_i
)
begin
if
(
rst_i
)
begin
RBR
<=
'b0
;
THR
<=
'b0
;
DLL
<=
'b0
;
DLM
<=
'b0
;
THR
<=
'b0
;
LCR
<=
'b0
;
LSR_OE
=
1'b0
;
LSR_PE
=
1'b0
;
LSR_FE
=
1'b0
;
LSR_BI
=
1'b0
;
LSR_THRE
=
1'b1
;
LSR_FIFO_ERROR
=
1'b0
;
LSR_DR
=
1'b0
;
dat_o
=
{
DATA_WIDTH
{
1'b0
}}
;
ack_o
=
1'b0
;
LSR_OE
<=
1'b0
;
LSR_PE
<=
1'b0
;
LSR_FE
<=
1'b0
;
LSR_BI
<=
1'b0
;
LSR_THRE
<=
1'b1
;
LSR_FIFO_ERROR
<=
1'b0
;
LSR_DR
<=
1'b0
;
dat_o
<=
{
DATA_WIDTH
{
1'b0
}}
;
ack_o
<=
1'b0
;
receiver_data_latched
<=
1'b0
;
end
else
begin
if
(
tsr_latched
)
LSR_THRE
=
1'b1
;
if
(
tsr_latched
)
LSR_THRE
<=
1'b1
;
if
(
receiver_framing_error
)
LSR_FE
<=
1'b1
;
if
(
receiver_data_latched
)
receiver_data_latched
<=
1'b0
;
if
(
receiver_data_ready
&
~
receiver_data_latched
)
begin
RBR
<=
receiver_data
;
receiver_data_latched
<=
1'b1
;
LSR_DR
<=
1'b1
;
if
(
LSR_DR
)
LSR_OE
<=
1'b1
;
end
if
(
cyc_i
&
stb_i
&
~
ack_o
)
begin
if
(
we_i
)
begin
case
(
adr_i
)
3'b000
:
// THR / DLL
if
(
LCR_DLAB
)
begin
DLL
=
dat_i
;
DLL
<
=
dat_i
;
end
else
begin
THR
=
dat_i
;
LSR_THRE
=
1'b0
;
THR
<
=
dat_i
;
LSR_THRE
<
=
1'b0
;
end
3'b011
:
// LCR
LCR
=
dat_i
;
LCR
<
=
dat_i
;
endcase
end
case
(
adr_i
)
3'b000
:
dat_o
=
LCR_DLAB
?
DLL
:
RBR
;
3'b011
:
dat_o
=
LCR
;
3'b000
:
begin
dat_o
<=
LCR_DLAB
?
DLL
:
RBR
;
if
(
~
LCR_DLAB
)
LSR_DR
<=
1'b0
;
end
3'b011
:
dat_o
<=
LCR
;
3'b101
:
begin
dat_o
=
LSR
;
LSR_OE
=
1'b0
;
LSR_PE
=
1'b0
;
LSR_FE
=
1'b0
;
LSR_BI
=
1'b0
;
dat_o
<
=
LSR
;
LSR_OE
<
=
1'b0
;
LSR_PE
<
=
1'b0
;
LSR_FE
<
=
1'b0
;
LSR_BI
<
=
1'b0
;
end
default:
dat_o
=
'b0
;
default:
dat_o
<
=
'b0
;
endcase
ack_o
=
1'b1
;
ack_o
<
=
1'b1
;
end
else
begin
ack_o
=
1'b0
;
ack_o
<
=
1'b0
;
end
end
end
...
...
src/verilog/wishbone/uart/uart_tb.v
View file @
8cb95d13
...
...
@@ -97,6 +97,8 @@ module uart_tb();
end
endtask
`include
"common/testbench_tasks/simulate_sin.v"
reg
[
TB_DATA_WIDTH
-
1
:
0
]
read_data
;
integer
retry_count
;
...
...
@@ -105,7 +107,7 @@ module uart_tb();
$
dumpvars
(
0
,
uart_tb
);
tb_rst_i
=
1'b1
;
tb_cyc_i
=
1'b0
;
tb_stb_i
=
1'b0
;
tb_we_i
=
1'b0
;
tb_adr_i
=
'b0
;
tb_dat_i
=
'b0
;
tb_sin
=
'b
0
;
tb_sin
=
'b
1
;
@
(
posedge
clk
);
@
(
negedge
clk
);
...
...
@@ -174,6 +176,61 @@ module uart_tb();
tb_assert
(
tb_sout
===
1'b1
,
"sout 1 when idling"
);
end
repeat
(
12
)
@
(
posedge
clk
);
simulate_sin
(
8'b01001011
,
"K"
,
TB_DIVIDER
);
wb_read
(
5
,
read_data
);
// LSR
tb_assert
(
read_data
[
0
]
===
1'b1
,
"DR asserted after rx byte 1"
);
tb_assert
(
read_data
[
1
]
===
1'b0
,
"OE deasserted after rx byte 1"
);
tb_assert
(
read_data
[
3
]
===
1'b0
,
"FE deasserted after rx byte 1"
);
wb_read
(
5
,
read_data
);
// LSR
tb_assert
(
read_data
[
0
]
===
1'b1
,
"DR asserted after rx byte 1, 2nd"
);
tb_assert
(
read_data
[
1
]
===
1'b0
,
"OE deasserted after rx byte 1, 2nd"
);
tb_assert
(
read_data
[
3
]
===
1'b0
,
"FE deasserted after rx byte 1, 2nd"
);
wb_read
(
0
,
read_data
);
// RBR
tb_assert
(
read_data
===
8'b01001011
);
wb_read
(
5
,
read_data
);
// LSR
tb_assert
(
read_data
[
0
]
===
1'b0
,
"DR deasserted after rx byte 1 read RBR"
);
tb_assert
(
read_data
[
1
]
===
1'b0
,
"OE deasserted after rx byte 1 read RBR"
);
tb_assert
(
read_data
[
3
]
===
1'b0
,
"FE deasserted after rx byte 1 read RBR"
);
simulate_sin
(
8'b01001011
,
"K"
,
TB_DIVIDER
);
simulate_sin
(
8'b01000111
,
"G"
,
TB_DIVIDER
);
wb_read
(
5
,
read_data
);
// LSR
tb_assert
(
read_data
[
0
]
===
1'b1
,
"DR asserted after rx byte 2&3"
);
tb_assert
(
read_data
[
1
]
===
1'b1
,
"OE asserted after rx byte 2&3"
);
tb_assert
(
read_data
[
3
]
===
1'b0
,
"FE deasserted after rx byte 2&3"
);
wb_read
(
5
,
read_data
);
// LSR
tb_assert
(
read_data
[
0
]
===
1'b1
,
"DR asserted after rx byte 2&3, 2nd"
);
tb_assert
(
read_data
[
1
]
===
1'b0
,
"OE deasserted after rx byte 2&3, 2nd"
);
tb_assert
(
read_data
[
3
]
===
1'b0
,
"FE deasserted after rx byte 2&3, 2nd"
);
wb_read
(
0
,
read_data
);
// RBR
tb_assert
(
read_data
===
8'b01000111
);
wb_read
(
5
,
read_data
);
// LSR
tb_assert
(
read_data
[
0
]
===
1'b0
,
"DR deasserted after rx byte 3 read RBR"
);
tb_assert
(
read_data
[
1
]
===
1'b0
,
"OE deasserted after rx byte 3 read RBR"
);
tb_assert
(
read_data
[
3
]
===
1'b0
,
"FE deasserted after rx byte 3 read RBR"
);
simulate_sin
(
8'b01001011
,
"K"
,
TB_DIVIDER
,
1'b0
);
wb_read
(
5
,
read_data
);
// LSR
tb_assert
(
read_data
[
0
]
===
1'b0
,
"DR deasserted after rx byte 4"
);
tb_assert
(
read_data
[
1
]
===
1'b0
,
"OE deasserted after rx byte 4"
);
tb_assert
(
read_data
[
3
]
===
1'b1
,
"FE asserted after rx byte 4"
);
wb_read
(
5
,
read_data
);
// LSR
tb_assert
(
read_data
[
0
]
===
1'b0
,
"DR deasserted after rx byte 4, 2nd"
);
tb_assert
(
read_data
[
1
]
===
1'b0
,
"OE deasserted after rx byte 4, 2nd"
);
tb_assert
(
read_data
[
3
]
===
1'b0
,
"FE deasserted after rx byte 4, 2nd"
);
$
display
(
"passed"
);
$
finish
;
end
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment