Created
February 10, 2010 03:37
-
-
Save epall/299997 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'Computer.Build' | |
controller = state_machine "ide_controller" do |m| | |
m.input :reset, VHDL::STD_LOGIC | |
m.input :instr_command, VHDL::STD_LOGIC_VECTOR(7..0) | |
m.input :instr_address, VHDL::STD_LOGIC_VECTOR(7..0) | |
m.input :instr_data, VHDL::STD_LOGIC_VECTOR(15..0) | |
m.output :result_command, VHDL::STD_LOGIC_VECTOR(7..0) | |
m.output :result_status, VHDL::STD_LOGIC_VECTOR(7..0) | |
m.output :result_data, VHDL::STD_LOGIC_VECTOR(15..0) | |
m.input :available_instr, VHDL::STD_LOGIC | |
m.output :read_instr, VHDL::STD_LOGIC | |
m.output :write_result, VHDL::STD_LOGIC | |
m.output :ide_reset_n, VHDL::STD_LOGIC | |
m.input :ide_data_in, VHDL::STD_LOGIC_VECTOR(15..0) | |
m.output :ide_data_out, VHDL::STD_LOGIC_VECTOR(15..0) | |
m.output :ide_data_write_n, VHDL::STD_LOGIC | |
m.output :ide_data_read_n, VHDL::STD_LOGIC | |
m.output :ide_address, VHDL::STD_LOGIC_VECTOR(2..0) | |
m.output :ide_cs_1f0_n, VHDL::STD_LOGIC | |
m.output :ide_cs_3f0_n, VHDL::STD_LOGIC | |
m.input :ide_ready, VHDL::STD_LOGIC | |
m.input :ide_int_request, VHDL::STD_LOGIC | |
m.input :ide_16_bit_n, VHDL::STD_LOGIC | |
m.input :ide_dasp_n, VHDL::STD_LOGIC | |
m.output :ide_data_OE, VHDL::STD_LOGIC | |
m.signal :command_buffer, VHDL::STD_LOGIC_VECTOR(7..0) | |
m.signal :address_buffer, VHDL::STD_LOGIC_VECTOR(7..0) | |
m.signal :data_buffer, VHDL::STD_LOGIC_VECTOR(15..0) | |
m.reset do |r| | |
r.goto :wait | |
r.low :ide_reset_n | |
r.high :ide_data_write_n | |
r.high :ide_data_read_n | |
r.assign :ide_address, '000' | |
r.high :ide_cs_1f0_n | |
r.high :ide_cs_3f0_n | |
r.assign :ide_data_out, '0000000000000000' | |
r.assign :result_command, "00000000" | |
r.assign :result_status, "00000000" | |
r.assign :result_data, "0000000000000000" | |
r.low :read_instr | |
r.low :write_result | |
end | |
m.state :wait do |s| | |
s.high :ide_reset_n | |
s.low :write_result | |
s.assign :read_instr, :available_instr | |
end | |
m.transition :from => :wait, :to => :decode, :on => equal(:available_instr, '1') | |
m.state :decode do |s| | |
s.assign :command_buffer, :instr_command | |
s.assign :address_buffer, :instr_address | |
s.assign :data_buffer, :instr_data | |
s.low :read_instr | |
s.case(:instr_command) do |c| | |
c["00000000"] = block do |b| | |
b.assign :result_command, :instr_command | |
b.assign :result_status, "00000000" | |
b.assign :result_data, "0000000000000000" | |
end | |
c["00000011"] = block do |b| | |
b.assign :result_command, :instr_command | |
b.assign :ide_address, 0, :instr_address, 0 | |
b.assign :ide_address, 1, :instr_address, 1 | |
b.assign :ide_address, 2, :instr_address, 2 | |
end | |
c["00000010"] = block do |b| | |
b.assign :result_command, :instr_command | |
b.assign :ide_address, 0, :instr_address, 0 | |
b.assign :ide_address, 1, :instr_address, 1 | |
b.assign :ide_address, 2, :instr_address, 2 | |
b.low :ide_cs_1f0_n | |
end | |
end | |
end | |
m.transition :from => :decode, :to => :writestatus, | |
:on => equal(:instr_command, "00000000") | |
m.transition :from => :decode, :to => :data_on_bus, | |
:on => equal(:instr_command, "00000011") | |
m.transition :from => :decode, :to => :data_on_bus, | |
:on => equal(:instr_command, "00000010") | |
m.state :writestatus do |s| | |
s.high :write_result | |
s.high :ide_cs_1f0_n | |
s.high :ide_data_read_n | |
end | |
m.transition :from => :writestatus, :to => :wait | |
m.state :action do |s| | |
ifelse = s.if equal(:instr_command, "00000011") do |b| | |
b.assign :result_data, :ide_data_in | |
end | |
ifelse.else do |b| | |
b.assign :result_data, "0000000000000000" | |
end | |
s.low :ide_data_OE | |
end | |
m.transition :from => :action, :to => :writestatus | |
m.state :data_on_bus do |s| | |
s.if equal(:command_buffer, "00000011") do |b| | |
b.high :ide_data_write_n | |
b.low :ide_data_read_n | |
end | |
end | |
m.transition :from => :data_on_bus, :to => :action, | |
:condition => equal(:command_buffer, "00000011") | |
end | |
generate_vhdl controller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
LIBRARY ieee; | |
USE ieee.std_logic_1164.all; | |
ENTITY ide_controller IS | |
PORT( | |
clock: in std_logic; | |
ide_16_bit_n: in STD_LOGIC; | |
ide_dasp_n: in STD_LOGIC; | |
instr_command: in STD_LOGIC_VECTOR(7 downto 0); | |
ide_data_in: in STD_LOGIC_VECTOR(15 downto 0); | |
instr_address: in STD_LOGIC_VECTOR(7 downto 0); | |
ide_ready: in STD_LOGIC; | |
available_instr: in STD_LOGIC; | |
reset: in STD_LOGIC; | |
instr_data: in STD_LOGIC_VECTOR(15 downto 0); | |
ide_int_request: in STD_LOGIC; | |
ide_data_read_n: out STD_LOGIC; | |
write_result: out STD_LOGIC; | |
ide_address: out STD_LOGIC_VECTOR(2 downto 0); | |
result_command: out STD_LOGIC_VECTOR(7 downto 0); | |
ide_reset_n: out STD_LOGIC; | |
ide_cs_1f0_n: out STD_LOGIC; | |
result_status: out STD_LOGIC_VECTOR(7 downto 0); | |
ide_data_OE: out STD_LOGIC; | |
ide_cs_3f0_n: out STD_LOGIC; | |
result_data: out STD_LOGIC_VECTOR(15 downto 0); | |
ide_data_out: out STD_LOGIC_VECTOR(15 downto 0); | |
ide_data_write_n: out STD_LOGIC; | |
read_instr: out STD_LOGIC | |
); | |
END ide_controller; | |
ARCHITECTURE arch_ide_controller OF ide_controller IS | |
TYPE STATE_TYPE IS ( state_wait, state_decode, state_writestatus, state_action, state_data_on_bus ); | |
SIGNAL state : STATE_TYPE; | |
SIGNAL command_buffer : STD_LOGIC_VECTOR(7 downto 0); | |
SIGNAL address_buffer : STD_LOGIC_VECTOR(7 downto 0); | |
SIGNAL data_buffer : STD_LOGIC_VECTOR(15 downto 0); | |
BEGIN | |
PROCESS(clock) | |
BEGIN | |
IF reset = '1' THEN | |
state <= state_wait; | |
ide_reset_n <= '0'; | |
ide_data_write_n <= '1'; | |
ide_data_read_n <= '1'; | |
ide_address <= "000"; | |
ide_cs_1f0_n <= '1'; | |
ide_cs_3f0_n <= '1'; | |
ide_data_out <= "0000000000000000"; | |
result_command <= "00000000"; | |
result_status <= "00000000"; | |
result_data <= "0000000000000000"; | |
read_instr <= '0'; | |
write_result <= '0'; | |
ELSIF clock'EVENT and clock = '1' THEN | |
CASE state IS | |
WHEN state_writestatus => | |
write_result <= '1'; | |
ide_cs_1f0_n <= '1'; | |
ide_data_read_n <= '1'; | |
WHEN state_wait => | |
ide_reset_n <= '1'; | |
write_result <= '0'; | |
read_instr <= available_instr; | |
WHEN state_action => | |
IF instr_command = "00000011" THEN | |
result_data <= ide_data_in; | |
ELSE | |
result_data <= "0000000000000000"; | |
END IF; | |
ide_data_OE <= '0'; | |
WHEN state_decode => | |
command_buffer <= instr_command; | |
address_buffer <= instr_address; | |
data_buffer <= instr_data; | |
read_instr <= '0'; | |
CASE instr_command IS | |
WHEN "00000010" => | |
result_command <= instr_command; | |
ide_address(0) <= instr_address(0); | |
ide_address(1) <= instr_address(1); | |
ide_address(2) <= instr_address(2); | |
ide_cs_1f0_n <= '0'; | |
WHEN "00000011" => | |
result_command <= instr_command; | |
ide_address(0) <= instr_address(0); | |
ide_address(1) <= instr_address(1); | |
ide_address(2) <= instr_address(2); | |
WHEN "00000000" => | |
result_command <= instr_command; | |
result_status <= "00000000"; | |
result_data <= "0000000000000000"; | |
END CASE; | |
WHEN state_data_on_bus => | |
IF command_buffer = "00000011" THEN | |
ide_data_write_n <= '1'; | |
ide_data_read_n <= '0'; | |
END IF; | |
END CASE; | |
END IF; | |
IF state = state_wait and available_instr = '1' THEN | |
state <= state_decode; | |
END IF; | |
IF state = state_decode and instr_command = "00000000" THEN | |
state <= state_writestatus; | |
END IF; | |
IF state = state_decode and instr_command = "00000011" THEN | |
state <= state_data_on_bus; | |
END IF; | |
IF state = state_decode and instr_command = "00000010" THEN | |
state <= state_data_on_bus; | |
END IF; | |
IF state = state_writestatus THEN | |
state <= state_wait; | |
END IF; | |
IF state = state_action THEN | |
state <= state_writestatus; | |
END IF; | |
IF state = state_data_on_bus and command_buffer = "00000011" THEN | |
state <= state_action; | |
END IF; | |
END PROCESS; | |
END arch_ide_controller; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment