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
8e2289a7
Commit
8e2289a7
authored
Aug 13, 2019
by
Koen Martens
Browse files
uart: first implementation, output only
parent
01a06812
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/verilog/wishbone/Makefile
View file @
8e2289a7
testsrc
=
$(
wildcard
*
_tb.v
)
SUBDIRS
:=
gpio
SUBDIRS
:=
gpio
uart
include
../common.mk
src/verilog/wishbone/uart/uart.v
0 → 100644
View file @
8e2289a7
module
uart
#(
parameter
DATA_WIDTH
=
8
,
parameter
ADDR_WIDTH
=
3
,
parameter
CLK_RATE
=
16000000
)(
input
wire
sin
,
output
reg
sout
,
// wishbone
input
wire
clk_i
,
input
wire
rst_i
,
input
wire
cyc_i
,
input
wire
stb_i
,
input
wire
we_i
,
output
reg
ack_o
,
input
wire
[
ADDR_WIDTH
-
1
:
0
]
adr_i
,
input
wire
[
DATA_WIDTH
-
1
:
0
]
dat_i
,
output
reg
[
DATA_WIDTH
-
1
:
0
]
dat_o
);
// internal registers
reg
[
7
:
0
]
RBR
;
/* Receiver Buffer Register (RO) */
reg
[
7
:
0
]
THR
;
/* Transmitter Holding Register (WO) */
reg
[
7
:
0
]
DLL
;
/* Divisor Latch (LS) */
reg
[
7
:
0
]
DLM
;
/* Divisor Latch (MS) */
reg
[
7
:
0
]
LCR
;
/* Line Control Register */
wire
LCR_DLAB
=
LCR
[
7
];
/* Divisor Latch Access Bit */
reg
[
7
:
0
]
LSR
;
/* Line Status Register */
localparam
LSR_BIT_THRE
=
5
;
localparam
LSR_BIT_TEMT
=
6
;
//
reg
[
15
:
0
]
clk_counter
;
reg
[
7
:
0
]
TSR
;
/* Transmitter Shift Register */
reg
[
3
:
0
]
transmit_bit_count
;
always
@
(
posedge
clk_i
)
begin
if
(
rst_i
||
(
clk_counter
==
0
))
begin
clk_counter
<=
{
DLM
,
DLL
}
;
end
else
begin
clk_counter
<=
clk_counter
-
1
;
end
end
always
@
(
posedge
clk_i
)
begin
if
(
rst_i
)
begin
RBR
<=
'b0
;
THR
<=
'b0
;
DLL
<=
'b0
;
DLM
<=
'b0
;
TSR
<=
1'b0
;
THR
<=
'b0
;
LCR
<=
'b0
;
LSR
<=
'b0
|
(
1
<<
LSR_BIT_THRE
)
|
(
1
<<
LSR_BIT_TEMT
);
sout
<=
1'b0
;
transmit_bit_count
<=
1'b0
;
transmit_state
<=
TRANSMIT_IDLE
;
dat_o
=
{
DATA_WIDTH
{
1'b0
}}
;
ack_o
=
1'b0
;
end
else
begin
if
(
cyc_i
&
stb_i
&
~
ack_o
)
begin
if
(
we_i
)
begin
case
(
adr_i
)
3'b000
:
// RBR / DLL
if
(
LCR_DLAB
)
begin
DLL
=
dat_i
;
end
3'b001
:
// THR / DLM
if
(
LCR_DLAB
)
begin
DLM
=
dat_i
;
end
else
begin
THR
=
dat_i
;
LSR
[
LSR_BIT_THRE
]
=
1'b0
;
end
3'b011
:
// LCR
LCR
=
dat_i
;
endcase
end
case
(
adr_i
)
3'b000
:
dat_o
=
LCR_DLAB
?
DLL
:
RBR
;
3'b011
:
dat_o
=
LCR
;
default:
dat_o
=
'b0
;
endcase
ack_o
=
1'b1
;
end
else
begin
ack_o
=
1'b0
;
end
end
end
// transmit
reg
[
2
:
0
]
transmit_state
;
localparam
TRANSMIT_IDLE
=
3'b001
;
localparam
TRANSMIT_SHIFT
=
3'b010
;
localparam
TRANSMIT_STOP
=
3'b100
;
always
@
(
posedge
clk_i
)
begin
if
(
clk_counter
==
0
)
begin
case
(
transmit_state
)
TRANSMIT_IDLE
:
begin
sout
=
1'b0
;
if
(
LSR
[
LSR_BIT_THRE
]
==
1'b0
)
begin
sout
=
1'b1
;
// start bit
TSR
=
THR
;
LSR
[
LSR_BIT_THRE
]
=
1'b1
;
transmit_bit_count
=
7
;
transmit_state
=
TRANSMIT_SHIFT
;
end
else
begin
transmit_state
=
TRANSMIT_IDLE
;
end
end
TRANSMIT_SHIFT
:
begin
if
(
transmit_bit_count
==
0
)
begin
transmit_state
=
TRANSMIT_STOP
;
end
sout
=
~
TSR
[
0
];
TSR
=
TSR
>>
1
;
transmit_state
=
(
transmit_bit_count
==
0
)
?
TRANSMIT_STOP
:
TRANSMIT_SHIFT
;
transmit_bit_count
=
transmit_bit_count
-
1
;
end
TRANSMIT_STOP
:
begin
sout
=
1'b0
;
transmit_state
=
TRANSMIT_IDLE
;
end
default
:
begin
sout
=
1'b0
;
transmit_state
=
TRANSMIT_IDLE
;
end
endcase
end
end
endmodule
src/verilog/wishbone/uart/uart_tb.v
0 → 100644
View file @
8e2289a7
`include
"common/testbench.v"
`include
"uart.v"
module
uart_tb
();
reg
clk
=
0
;
always
#
0.5
clk
=
~
clk
;
parameter
TB_DATA_WIDTH
=
8
;
parameter
TB_ADDR_WIDTH
=
3
;
reg
tb_rst_i
;
reg
tb_cyc_i
;
reg
tb_stb_i
;
reg
tb_we_i
;
wire
tb_ack_o
;
reg
[
TB_ADDR_WIDTH
-
1
:
0
]
tb_adr_i
;
reg
[
TB_DATA_WIDTH
-
1
:
0
]
tb_dat_i
;
wire
[
TB_DATA_WIDTH
-
1
:
0
]
tb_dat_o
;
reg
tb_sin
;
wire
tb_sout
;
wire
tb_delayed_rst_i
;
wire
tb_delayed_cyc_i
;
wire
tb_delayed_stb_i
;
wire
tb_delayed_we_i
;
wire
tb_delay_ack_o
;
wire
[
TB_ADDR_WIDTH
-
1
:
0
]
tb_delayed_adr_i
;
wire
[
TB_DATA_WIDTH
-
1
:
0
]
tb_delayed_dat_i
;
wire
[
TB_DATA_WIDTH
-
1
:
0
]
tb_delay_dat_o
;
wire
tb_delayed_sin
;
wire
tb_delay_sout
;
assign
#
`TB_IN_DELAY
tb_delayed_rst_i
=
tb_rst_i
;
assign
#
`TB_IN_DELAY
tb_delayed_cyc_i
=
tb_cyc_i
;
assign
#
`TB_IN_DELAY
tb_delayed_stb_i
=
tb_stb_i
;
assign
#
`TB_IN_DELAY
tb_delayed_we_i
=
tb_we_i
;
assign
#
`TB_IN_DELAY
tb_delayed_adr_i
=
tb_adr_i
;
assign
#
`TB_IN_DELAY
tb_delayed_dat_i
=
tb_dat_i
;
assign
#
`TB_IN_DELAY
tb_delayed_sin
=
tb_sin
;
assign
#
`TB_IN_DELAY
tb_ack_o
=
tb_delay_ack_o
;
assign
#
`TB_IN_DELAY
tb_dat_o
=
tb_delay_dat_o
;
assign
#
`TB_IN_DELAY
tb_sout
=
tb_delay_sout
;
uart
#(
.
DATA_WIDTH
(
TB_DATA_WIDTH
)
)
UUT
(
.
sout
(
tb_delay_sout
),
.
sin
(
tb_delayed_sin
),
.
clk_i
(
clk
),
.
rst_i
(
tb_delayed_rst_i
),
.
cyc_i
(
tb_delayed_cyc_i
),
.
stb_i
(
tb_delayed_stb_i
),
.
we_i
(
tb_delayed_we_i
),
.
ack_o
(
tb_delay_ack_o
),
.
adr_i
(
tb_delayed_adr_i
),
.
dat_i
(
tb_delayed_dat_i
),
.
dat_o
(
tb_delay_dat_o
)
);
`include
"common/testbench_tasks/tb_assert.v"
`include
"common/testbench_tasks/wb_read.v"
`include
"common/testbench_tasks/wb_write.v"
initial
begin
$
dumpfile
(
`VCD_OUTPUT
);
$
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
=
'b0
;
@
(
posedge
clk
);
@
(
negedge
clk
);
tb_assert
(
tb_ack_o
===
1'b0
,
"reset ack_o"
);
@
(
posedge
clk
);
tb_rst_i
=
1'b0
;
tb_dat_i
=
'bx
;
@
(
negedge
clk
);
tb_assert
(
tb_ack_o
===
1'b0
,
"post-reset ack_o"
);
// set DLAB (bit7) in LCR (reg 3)
wb_write
(
3
,
8'h80
);
// set DL = 0x0683 (=1667, 16MHz/1667 -> 9598 baud ~ 9600)
wb_write
(
0
,
8'h03
);
wb_write
(
1
,
8'h00
);
@
(
posedge
clk
);
@
(
posedge
clk
);
// reset DLAB (bit7) in LCR (reg 3)
wb_write
(
3
,
8'h00
);
// write 'K' to THR (reg 1)
wb_write
(
1
,
8'h4b
);
repeat
(
200
)
begin
wb_read
(
5
,
8'h00
);
end
// read input register
//wb_read(0, 8'h00);
//tb_assert(tb_uart_out === 8'h00, "uart out is 0");
$
display
(
"passed"
);
$
finish
;
end
endmodule
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