Skip to content

Commit 861c1ef

Browse files
Proof of concept periph 0 UART
1 parent ac61b10 commit 861c1ef

12 files changed

+129
-22
lines changed

hdl/ip/vhd/espi/espi_spec_regs.rdl

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ addrmap eSPI_Spec {
100100
field {
101101
desc = "OOB Message Channel Supported";
102102
sw = r;
103-
} oob_support[2:2] = 0x1;
103+
} oob_support[2:2] = 0x0;
104104
field {
105105
desc = "Virtual Wire Channel Supported";
106106
sw = r;

hdl/ip/vhd/espi/espi_target_top.vhd

-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,6 @@ begin
220220
clk => clk,
221221
reset => reset,
222222
axi_if => axi_if,
223-
msg_en => msg_en,
224223
dbg_chan => dbg_chan
225224
);
226225

hdl/ip/vhd/espi/link_layer/cmd_sizer.vhd

+3-3
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,16 @@ begin
102102

103103
when tag_len =>
104104
if byte_transfer then
105-
v.state := tag_len;
106-
v.hdr.len(11 downto 8) := cmd.data(3 downto 0);
105+
v.state := len;
106+
v.hdr.len(7 downto 0) := cmd.data(7 downto 0);
107107
end if;
108108
if cs_n = '1' then
109109
v.size_info.valid := '0';
110110
v.state := idle;
111111
end if;
112112

113113
when len =>
114-
if known_size_by_cycle_type(r.hdr) then
114+
if known_size_by_length(r.hdr) then
115115
v.state := size_known;
116116
v.size_info.size := size_by_header(r.hdr);
117117
elsif byte_transfer then

hdl/ip/vhd/espi/link_layer/link_layer_pkg.vhd

+3
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ package body link_layer_pkg is
147147
when message_with_data =>
148148
-- opcode, standard header (3), 5 mesg header bytes, length bytes, crc
149149
return To_StdLogicVector(1 + 3 + 5 + to_integer(h.len) + 1, 13);
150+
when mem_write_32 =>
151+
-- opcode, standard header (3), 4 addr bytes, length bytes, crc
152+
return To_StdLogicVector(1 + 3 + 4 + to_integer(h.len) + 1, 13);
150153
when others =>
151154
assert false report "Unsupported cycle type" severity failure;
152155
return To_StdLogicVector(0, 13);

hdl/ip/vhd/espi/peripheral_channel/uart_channel_top.vhd

+5-3
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ begin
8282
np_free <= '0';
8383
np_avail <= '0';
8484
pc_free <= '1' when (fifo_depth - rx_wusedwds) >= max_msg_size else '0';
85-
pc_avail <= (not tx_rempty) and pc_avail_not_masked and msg_not_oob_syncd;
86-
oob_free <= '1' when (fifo_depth - rx_wusedwds) >= max_msg_size else '0';
87-
oob_avail <= (not tx_rempty) and pc_avail_not_masked and (not msg_not_oob_syncd);
85+
pc_avail <= '0'; --(not tx_rempty) and pc_avail_not_masked and msg_not_oob_syncd;
86+
oob_free <= '0'; --'1' when (fifo_depth - rx_wusedwds) >= max_msg_size else '0';
87+
oob_avail <= '0'; --(not tx_rempty) and pc_avail_not_masked and (not msg_not_oob_syncd);
8888

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

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

98+
-- Need a bit of a re-write here.
99+
98100
-- We want to hold some data to let the bytes accumulate
99101
-- so that we're not doing multiple transactions (which are multi-byte)
100102
-- but just transferring 1-2 bytes at a time.

hdl/ip/vhd/espi/sims/espi_tb.vhd

+20
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,26 @@ begin
220220
dbg_get_response(net, payload_size + 12 , response);
221221
check(response.crc_ok, "Response UART data resp CRC Check failed");
222222
compare_uart_loopback(my_queue, response.queue);
223+
elsif run("put_mem_write32") then
224+
my_queue := build_rand_byte_queue(4);
225+
put_mem_write32(net, X"00000000", To_Std_Logic_Vector(4,12), my_queue, response_code, status, crc_ok);
226+
check(crc_ok, "put mem write32 CRC Check failed");
227+
dbg_get_response(net, 4 , response);
228+
check(response.crc_ok, "put mem write32 resp CRC Check failed");
229+
230+
get_status(net, response_code, status, crc_ok);
231+
check(crc_ok, "get status CRC Check failed");
232+
233+
elsif run("put_invalid_len_mem_write32") then
234+
my_queue := build_rand_byte_queue(5); -- one extra byte here
235+
put_mem_write32(net, X"00000000", To_Std_Logic_Vector(4,12), my_queue, response_code, status, crc_ok);
236+
check(crc_ok, "put mem write32 CRC Check failed");
237+
dbg_get_response(net, 4 , response);
238+
check(response.crc_ok, "put mem write32 resp CRC Check failed");
239+
240+
get_status(net, response_code, status, crc_ok);
241+
check(crc_ok, "get status CRC Check failed");
242+
223243
elsif run("put_iowr_short") then
224244
put_iowr_short4(net, X"0080", X"EE0000A2", response_code, status, crc_ok);
225245
dbg_get_response(net, 4 , response);

hdl/ip/vhd/espi/sims/espi_tb_pkg.vhd

+54-8
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ package espi_tb_pkg is
9090
constant address: in std_logic_vector(15 downto 0);
9191
constant data : in std_logic_vector(31 downto 0);
9292
constant bad_crc : boolean := false) return cmd_t;
93+
94+
impure function build_mem_write32(
95+
constant address: in std_logic_vector(31 downto 0);
96+
constant payload_len : in std_logic_vector(11 downto 0);
97+
constant payload : queue_t;
98+
constant bad_crc : boolean := false) return cmd_t;
9399

94100
procedure compare_uart_loopback(
95101
constant input_payload : queue_t;
@@ -378,14 +384,14 @@ package body espi_tb_pkg is
378384
constant bad_crc : boolean := false) return cmd_t is
379385
variable cmd : cmd_t := (new_queue, 0);
380386
begin
381-
-- OPCODE_GET_PC (1 byte)
382-
push_byte(cmd.queue, to_integer(opcode_put_iowr_short_4byte));
383-
cmd.num_bytes := cmd.num_bytes + 1;
384-
-- address 2 bytes
385-
push_byte(cmd.queue, to_integer(address(15 downto 8)));
386-
cmd.num_bytes := cmd.num_bytes + 1;
387-
push_byte(cmd.queue, to_integer(address(7 downto 0)));
388-
cmd.num_bytes := cmd.num_bytes + 1;
387+
-- OPCODE_PUT_IOWR_SHORT (1 byte)
388+
push_byte(cmd.queue, to_integer(opcode_put_iowr_short_4byte));
389+
cmd.num_bytes := cmd.num_bytes + 1;
390+
-- address 2 bytes
391+
push_byte(cmd.queue, to_integer(address(15 downto 8)));
392+
cmd.num_bytes := cmd.num_bytes + 1;
393+
push_byte(cmd.queue, to_integer(address(7 downto 0)));
394+
cmd.num_bytes := cmd.num_bytes + 1;
389395
-- data 4 bytes
390396
push_byte(cmd.queue, to_integer(data(7 downto 0)));
391397
cmd.num_bytes := cmd.num_bytes + 1;
@@ -402,4 +408,44 @@ package body espi_tb_pkg is
402408
return cmd;
403409
end function;
404410

411+
impure function build_mem_write32(
412+
constant address: in std_logic_vector(31 downto 0);
413+
constant payload_len : in std_logic_vector(11 downto 0);
414+
constant payload : queue_t;
415+
constant bad_crc : boolean := false) return cmd_t is
416+
variable cmd : cmd_t := (new_queue, 0);
417+
begin
418+
-- OPCODE_GET_PC (1 byte)
419+
push_byte(cmd.queue, to_integer(opcode_put_pc));
420+
cmd.num_bytes := cmd.num_bytes + 1;
421+
-- cycle type (1 byte)
422+
push_byte(cmd.queue, to_integer(mem_write_32));
423+
cmd.num_bytes := cmd.num_bytes + 1;
424+
-- tag/length high
425+
push_byte(cmd.queue, to_integer("0000" & payload_len(11 downto 8)));
426+
cmd.num_bytes := cmd.num_bytes + 1;
427+
-- length low
428+
push_byte(cmd.queue, to_integer(payload_len(7 downto 0)));
429+
cmd.num_bytes := cmd.num_bytes + 1;
430+
-- address 4 bytes
431+
push_byte(cmd.queue, to_integer(address(31 downto 24)));
432+
cmd.num_bytes := cmd.num_bytes + 1;
433+
push_byte(cmd.queue, to_integer(address(23 downto 16)));
434+
cmd.num_bytes := cmd.num_bytes + 1;
435+
push_byte(cmd.queue, to_integer(address(15 downto 8)));
436+
cmd.num_bytes := cmd.num_bytes + 1;
437+
push_byte(cmd.queue, to_integer(address(7 downto 0)));
438+
cmd.num_bytes := cmd.num_bytes + 1;
439+
-- data length bytes
440+
while not is_empty(payload) loop
441+
push_byte(cmd.queue, pop_byte(payload));
442+
cmd.num_bytes := cmd.num_bytes + 1;
443+
end loop;
444+
-- CRC (1 byte)
445+
push_byte(cmd.queue, to_integer(crc8(cmd.queue)));
446+
cmd.num_bytes := cmd.num_bytes + 1;
447+
448+
return cmd;
449+
end function;
450+
405451
end package body;

hdl/ip/vhd/espi/sims/models/espi_controller_vc_pkg.vhd

+33
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ package espi_controller_vc_pkg is
8383
variable crc_ok : inout boolean
8484
);
8585

86+
procedure put_mem_write32(
87+
signal net : inout network_t;
88+
constant address : in std_logic_vector(31 downto 0);
89+
constant payload_len : in std_logic_vector(11 downto 0);
90+
constant payload_data : in queue_t;
91+
variable response_code: inout std_logic_vector(7 downto 0);
92+
variable status : inout std_logic_vector(15 downto 0);
93+
variable crc_ok : inout boolean
94+
);
95+
8696
procedure get_any_pending_alert(
8797
signal net : inout network_t;
8898
variable alert : out boolean
@@ -288,6 +298,29 @@ package body espi_controller_vc_pkg is
288298
response_code := std_logic_vector(to_unsigned(pop_byte(rx_queue), 8));
289299
status := get_status_from_queue_and_flush(rx_queue);
290300
end procedure;
301+
302+
procedure put_mem_write32(
303+
signal net : inout network_t;
304+
constant address : in std_logic_vector(31 downto 0);
305+
constant payload_len : in std_logic_vector(11 downto 0);
306+
constant payload_data : in queue_t;
307+
variable response_code: inout std_logic_vector(7 downto 0);
308+
variable status : inout std_logic_vector(15 downto 0);
309+
variable crc_ok : inout boolean
310+
) is
311+
variable cmd : cmd_t := (new_queue, 0);
312+
variable rx_bytes : integer := 4; -- response, 16bit status, 1 crc,
313+
variable msg_target : actor_t := find("espi_vc");
314+
variable rx_queue : queue_t := new_queue;
315+
begin
316+
cmd := build_mem_write32(address, payload_len, payload_data);
317+
enqueue_tx_data_bytes(net, msg_target, cmd.num_bytes, cmd.queue);
318+
enqueue_transaction(net, msg_target, cmd.num_bytes, rx_bytes);
319+
get_rx_queue(net, msg_target, rx_queue);
320+
crc_ok := check_queue_crc(rx_queue); -- non-destructive to queue
321+
response_code := std_logic_vector(to_unsigned(pop_byte(rx_queue), 8));
322+
status := get_status_from_queue_and_flush(rx_queue);
323+
end procedure;
291324

292325
procedure get_any_pending_alert(
293326
signal net : inout network_t;

hdl/ip/vhd/espi/sys_regs/espi_regs.rdl

-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ addrmap espi_regs {
2323
reg {
2424
name = "Control Register";
2525
desc = "";
26-
field {
27-
desc = "Respond back on periph 0 channel vs oob";
28-
} msg_en[4:4] = 0;
2926
field {
3027
desc = "Set to one to reset the command FIFO. Cleared by hardware after reset.";
3128
} cmd_fifo_reset[3:3] = 0;

hdl/ip/vhd/espi/sys_regs/espi_regs.vhd

-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ entity espi_regs is
2020
reset : in std_logic;
2121
-- axi interface
2222
axi_if : view axil_target;
23-
msg_en : out std_logic;
2423
-- debug interface
2524
dbg_chan : view dbg_regs_if
2625

@@ -49,7 +48,6 @@ begin
4948
fifo_status_reg.resp_used_wds <= dbg_chan.rdstatus.usedwds;
5049
status_reg.busy <= dbg_chan.busy;
5150
flags_reg.alert <= dbg_chan.alert_pending;
52-
msg_en <= control_reg.msg_en;
5351

5452
-- unpack the record
5553
axi_if.write_response.resp <= OKAY;

hdl/ip/vhd/espi/txn_layer/command_processor.vhd

+8-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,12 @@ architecture rtl of command_processor is
138138
next_state.next_state := parse_msg_header;
139139
next_state.cmd_addr_bytes := 0;
140140
next_state.cmd_payload_bytes := to_integer(header.length);
141+
when mem_write_32 =>
142+
-- mem writes have a payload of "length"
143+
next_state.next_state := parse_addr_header;
144+
next_state.cmd_payload_bytes := to_integer(header.length);
141145
when others =>
146+
-- use the default value for next_state
142147
null;
143148
end case;
144149
when opcode_put_oob =>
@@ -163,7 +168,9 @@ begin
163168
vwire_if.wstrobe <= r.vwire_wstrobe;
164169

165170
host_to_sp_espi.data <= data_from_host.data;
166-
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
171+
host_to_sp_espi.valid <= data_from_host.valid when r.cmd_header.opcode.value = opcode_put_pc and
172+
(r.cmd_header.cycle_kind = message_with_data or
173+
r.cmd_header.cycle_kind = mem_write_32) and r.state = parse_data else
167174
data_from_host.valid when r.cmd_header.opcode.value = opcode_put_oob and r.state = parse_data else '0';
168175
-- pass through the flash channel requests here
169176
flash_req.espi_hdr <= r.cmd_header;

hdl/ip/vhd/espi/txn_layer/espi_protocol_pkg.vhd

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ package espi_protocol_pkg is
4242
-- eSPI Channel
4343
constant mem_read_32 : std_logic_vector(7 downto 0) := "00000000";
4444
constant mem_read_64 : std_logic_vector(7 downto 0) := "00000010";
45+
constant mem_write_32 : std_logic_vector(7 downto 0) := "00000001";
46+
constant mem_write_64 : std_logic_vector(7 downto 0) := "00000011";
4547
-- Flash channel (from server addendum)
4648
constant flash_read : std_logic_vector(7 downto 0) := "00000000";
4749
constant success_no_data : std_logic_vector(7 downto 0) := "00000110";

0 commit comments

Comments
 (0)