Skip to content

Commit

Permalink
Proof of concept periph 0 UART
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanaelhuffman committed Nov 18, 2024
1 parent ac61b10 commit 861c1ef
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 22 deletions.
2 changes: 1 addition & 1 deletion hdl/ip/vhd/espi/espi_spec_regs.rdl
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ addrmap eSPI_Spec {
field {
desc = "OOB Message Channel Supported";
sw = r;
} oob_support[2:2] = 0x1;
} oob_support[2:2] = 0x0;
field {
desc = "Virtual Wire Channel Supported";
sw = r;
Expand Down
1 change: 0 additions & 1 deletion hdl/ip/vhd/espi/espi_target_top.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ begin
clk => clk,
reset => reset,
axi_if => axi_if,
msg_en => msg_en,
dbg_chan => dbg_chan
);

Expand Down
6 changes: 3 additions & 3 deletions hdl/ip/vhd/espi/link_layer/cmd_sizer.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,16 @@ begin

when tag_len =>
if byte_transfer then
v.state := tag_len;
v.hdr.len(11 downto 8) := cmd.data(3 downto 0);
v.state := len;
v.hdr.len(7 downto 0) := cmd.data(7 downto 0);
end if;
if cs_n = '1' then
v.size_info.valid := '0';
v.state := idle;
end if;

when len =>
if known_size_by_cycle_type(r.hdr) then
if known_size_by_length(r.hdr) then
v.state := size_known;
v.size_info.size := size_by_header(r.hdr);
elsif byte_transfer then
Expand Down
3 changes: 3 additions & 0 deletions hdl/ip/vhd/espi/link_layer/link_layer_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ package body link_layer_pkg is
when message_with_data =>
-- opcode, standard header (3), 5 mesg header bytes, length bytes, crc
return To_StdLogicVector(1 + 3 + 5 + to_integer(h.len) + 1, 13);
when mem_write_32 =>
-- opcode, standard header (3), 4 addr bytes, length bytes, crc
return To_StdLogicVector(1 + 3 + 4 + to_integer(h.len) + 1, 13);
when others =>
assert false report "Unsupported cycle type" severity failure;
return To_StdLogicVector(0, 13);
Expand Down
8 changes: 5 additions & 3 deletions hdl/ip/vhd/espi/peripheral_channel/uart_channel_top.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ begin
np_free <= '0';
np_avail <= '0';
pc_free <= '1' when (fifo_depth - rx_wusedwds) >= max_msg_size else '0';
pc_avail <= (not tx_rempty) and pc_avail_not_masked and msg_not_oob_syncd;
oob_free <= '1' when (fifo_depth - rx_wusedwds) >= max_msg_size else '0';
oob_avail <= (not tx_rempty) and pc_avail_not_masked and (not msg_not_oob_syncd);
pc_avail <= '0'; --(not tx_rempty) and pc_avail_not_masked and msg_not_oob_syncd;
oob_free <= '0'; --'1' when (fifo_depth - rx_wusedwds) >= max_msg_size else '0';
oob_avail <= '0'; --(not tx_rempty) and pc_avail_not_masked and (not msg_not_oob_syncd);

host_to_sp_espi.ready <= not rx_wfull;
-- tx_rusedwds is potentailly cycles behind the empty flag due to fifo latencies.
Expand All @@ -95,6 +95,8 @@ begin

fifo_read_by_espi <= sp_to_host_espi.st.valid and sp_to_host_espi.st.ready;

-- Need a bit of a re-write here.

-- We want to hold some data to let the bytes accumulate
-- so that we're not doing multiple transactions (which are multi-byte)
-- but just transferring 1-2 bytes at a time.
Expand Down
20 changes: 20 additions & 0 deletions hdl/ip/vhd/espi/sims/espi_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,26 @@ begin
dbg_get_response(net, payload_size + 12 , response);
check(response.crc_ok, "Response UART data resp CRC Check failed");
compare_uart_loopback(my_queue, response.queue);
elsif run("put_mem_write32") then
my_queue := build_rand_byte_queue(4);
put_mem_write32(net, X"00000000", To_Std_Logic_Vector(4,12), my_queue, response_code, status, crc_ok);
check(crc_ok, "put mem write32 CRC Check failed");
dbg_get_response(net, 4 , response);
check(response.crc_ok, "put mem write32 resp CRC Check failed");

get_status(net, response_code, status, crc_ok);
check(crc_ok, "get status CRC Check failed");

elsif run("put_invalid_len_mem_write32") then
my_queue := build_rand_byte_queue(5); -- one extra byte here
put_mem_write32(net, X"00000000", To_Std_Logic_Vector(4,12), my_queue, response_code, status, crc_ok);
check(crc_ok, "put mem write32 CRC Check failed");
dbg_get_response(net, 4 , response);
check(response.crc_ok, "put mem write32 resp CRC Check failed");

get_status(net, response_code, status, crc_ok);
check(crc_ok, "get status CRC Check failed");

elsif run("put_iowr_short") then
put_iowr_short4(net, X"0080", X"EE0000A2", response_code, status, crc_ok);
dbg_get_response(net, 4 , response);
Expand Down
62 changes: 54 additions & 8 deletions hdl/ip/vhd/espi/sims/espi_tb_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ package espi_tb_pkg is
constant address: in std_logic_vector(15 downto 0);
constant data : in std_logic_vector(31 downto 0);
constant bad_crc : boolean := false) return cmd_t;

impure function build_mem_write32(
constant address: in std_logic_vector(31 downto 0);
constant payload_len : in std_logic_vector(11 downto 0);
constant payload : queue_t;
constant bad_crc : boolean := false) return cmd_t;

procedure compare_uart_loopback(
constant input_payload : queue_t;
Expand Down Expand Up @@ -378,14 +384,14 @@ package body espi_tb_pkg is
constant bad_crc : boolean := false) return cmd_t is
variable cmd : cmd_t := (new_queue, 0);
begin
-- OPCODE_GET_PC (1 byte)
push_byte(cmd.queue, to_integer(opcode_put_iowr_short_4byte));
cmd.num_bytes := cmd.num_bytes + 1;
-- address 2 bytes
push_byte(cmd.queue, to_integer(address(15 downto 8)));
cmd.num_bytes := cmd.num_bytes + 1;
push_byte(cmd.queue, to_integer(address(7 downto 0)));
cmd.num_bytes := cmd.num_bytes + 1;
-- OPCODE_PUT_IOWR_SHORT (1 byte)
push_byte(cmd.queue, to_integer(opcode_put_iowr_short_4byte));
cmd.num_bytes := cmd.num_bytes + 1;
-- address 2 bytes
push_byte(cmd.queue, to_integer(address(15 downto 8)));
cmd.num_bytes := cmd.num_bytes + 1;
push_byte(cmd.queue, to_integer(address(7 downto 0)));
cmd.num_bytes := cmd.num_bytes + 1;
-- data 4 bytes
push_byte(cmd.queue, to_integer(data(7 downto 0)));
cmd.num_bytes := cmd.num_bytes + 1;
Expand All @@ -402,4 +408,44 @@ package body espi_tb_pkg is
return cmd;
end function;

impure function build_mem_write32(
constant address: in std_logic_vector(31 downto 0);
constant payload_len : in std_logic_vector(11 downto 0);
constant payload : queue_t;
constant bad_crc : boolean := false) return cmd_t is
variable cmd : cmd_t := (new_queue, 0);
begin
-- OPCODE_GET_PC (1 byte)
push_byte(cmd.queue, to_integer(opcode_put_pc));
cmd.num_bytes := cmd.num_bytes + 1;
-- cycle type (1 byte)
push_byte(cmd.queue, to_integer(mem_write_32));
cmd.num_bytes := cmd.num_bytes + 1;
-- tag/length high
push_byte(cmd.queue, to_integer("0000" & payload_len(11 downto 8)));
cmd.num_bytes := cmd.num_bytes + 1;
-- length low
push_byte(cmd.queue, to_integer(payload_len(7 downto 0)));
cmd.num_bytes := cmd.num_bytes + 1;
-- address 4 bytes
push_byte(cmd.queue, to_integer(address(31 downto 24)));
cmd.num_bytes := cmd.num_bytes + 1;
push_byte(cmd.queue, to_integer(address(23 downto 16)));
cmd.num_bytes := cmd.num_bytes + 1;
push_byte(cmd.queue, to_integer(address(15 downto 8)));
cmd.num_bytes := cmd.num_bytes + 1;
push_byte(cmd.queue, to_integer(address(7 downto 0)));
cmd.num_bytes := cmd.num_bytes + 1;
-- data length bytes
while not is_empty(payload) loop
push_byte(cmd.queue, pop_byte(payload));
cmd.num_bytes := cmd.num_bytes + 1;
end loop;
-- CRC (1 byte)
push_byte(cmd.queue, to_integer(crc8(cmd.queue)));
cmd.num_bytes := cmd.num_bytes + 1;

return cmd;
end function;

end package body;
33 changes: 33 additions & 0 deletions hdl/ip/vhd/espi/sims/models/espi_controller_vc_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ package espi_controller_vc_pkg is
variable crc_ok : inout boolean
);

procedure put_mem_write32(
signal net : inout network_t;
constant address : in std_logic_vector(31 downto 0);
constant payload_len : in std_logic_vector(11 downto 0);
constant payload_data : in queue_t;
variable response_code: inout std_logic_vector(7 downto 0);
variable status : inout std_logic_vector(15 downto 0);
variable crc_ok : inout boolean
);

procedure get_any_pending_alert(
signal net : inout network_t;
variable alert : out boolean
Expand Down Expand Up @@ -288,6 +298,29 @@ package body espi_controller_vc_pkg is
response_code := std_logic_vector(to_unsigned(pop_byte(rx_queue), 8));
status := get_status_from_queue_and_flush(rx_queue);
end procedure;

procedure put_mem_write32(
signal net : inout network_t;
constant address : in std_logic_vector(31 downto 0);
constant payload_len : in std_logic_vector(11 downto 0);
constant payload_data : in queue_t;
variable response_code: inout std_logic_vector(7 downto 0);
variable status : inout std_logic_vector(15 downto 0);
variable crc_ok : inout boolean
) is
variable cmd : cmd_t := (new_queue, 0);
variable rx_bytes : integer := 4; -- response, 16bit status, 1 crc,
variable msg_target : actor_t := find("espi_vc");
variable rx_queue : queue_t := new_queue;
begin
cmd := build_mem_write32(address, payload_len, payload_data);
enqueue_tx_data_bytes(net, msg_target, cmd.num_bytes, cmd.queue);
enqueue_transaction(net, msg_target, cmd.num_bytes, rx_bytes);
get_rx_queue(net, msg_target, rx_queue);
crc_ok := check_queue_crc(rx_queue); -- non-destructive to queue
response_code := std_logic_vector(to_unsigned(pop_byte(rx_queue), 8));
status := get_status_from_queue_and_flush(rx_queue);
end procedure;

procedure get_any_pending_alert(
signal net : inout network_t;
Expand Down
3 changes: 0 additions & 3 deletions hdl/ip/vhd/espi/sys_regs/espi_regs.rdl
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ addrmap espi_regs {
reg {
name = "Control Register";
desc = "";
field {
desc = "Respond back on periph 0 channel vs oob";
} msg_en[4:4] = 0;
field {
desc = "Set to one to reset the command FIFO. Cleared by hardware after reset.";
} cmd_fifo_reset[3:3] = 0;
Expand Down
2 changes: 0 additions & 2 deletions hdl/ip/vhd/espi/sys_regs/espi_regs.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ entity espi_regs is
reset : in std_logic;
-- axi interface
axi_if : view axil_target;
msg_en : out std_logic;
-- debug interface
dbg_chan : view dbg_regs_if

Expand Down Expand Up @@ -49,7 +48,6 @@ begin
fifo_status_reg.resp_used_wds <= dbg_chan.rdstatus.usedwds;
status_reg.busy <= dbg_chan.busy;
flags_reg.alert <= dbg_chan.alert_pending;
msg_en <= control_reg.msg_en;

-- unpack the record
axi_if.write_response.resp <= OKAY;
Expand Down
9 changes: 8 additions & 1 deletion hdl/ip/vhd/espi/txn_layer/command_processor.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,12 @@ architecture rtl of command_processor is
next_state.next_state := parse_msg_header;
next_state.cmd_addr_bytes := 0;
next_state.cmd_payload_bytes := to_integer(header.length);
when mem_write_32 =>
-- mem writes have a payload of "length"
next_state.next_state := parse_addr_header;
next_state.cmd_payload_bytes := to_integer(header.length);
when others =>
-- use the default value for next_state
null;
end case;
when opcode_put_oob =>
Expand All @@ -163,7 +168,9 @@ begin
vwire_if.wstrobe <= r.vwire_wstrobe;

host_to_sp_espi.data <= data_from_host.data;
host_to_sp_espi.valid <= data_from_host.valid when r.cmd_header.opcode.value = opcode_put_pc and r.cmd_header.cycle_kind = message_with_data and r.state = parse_data else
host_to_sp_espi.valid <= data_from_host.valid when r.cmd_header.opcode.value = opcode_put_pc and
(r.cmd_header.cycle_kind = message_with_data or
r.cmd_header.cycle_kind = mem_write_32) and r.state = parse_data else
data_from_host.valid when r.cmd_header.opcode.value = opcode_put_oob and r.state = parse_data else '0';
-- pass through the flash channel requests here
flash_req.espi_hdr <= r.cmd_header;
Expand Down
2 changes: 2 additions & 0 deletions hdl/ip/vhd/espi/txn_layer/espi_protocol_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ package espi_protocol_pkg is
-- eSPI Channel
constant mem_read_32 : std_logic_vector(7 downto 0) := "00000000";
constant mem_read_64 : std_logic_vector(7 downto 0) := "00000010";
constant mem_write_32 : std_logic_vector(7 downto 0) := "00000001";
constant mem_write_64 : std_logic_vector(7 downto 0) := "00000011";
-- Flash channel (from server addendum)
constant flash_read : std_logic_vector(7 downto 0) := "00000000";
constant success_no_data : std_logic_vector(7 downto 0) := "00000110";
Expand Down

0 comments on commit 861c1ef

Please sign in to comment.