mirror of
https://github.com/array-in-a-matrix/SAROO.git
synced 2025-04-02 10:31:43 -04:00
150 lines
2.9 KiB
Verilog
150 lines
2.9 KiB
Verilog
|
|
///////////////////////////////////////////////////////
|
|
// Module: external bus master for Saturn ABUS //
|
|
///////////////////////////////////////////////////////
|
|
|
|
module saturn_master(
|
|
addr, ale, ncs, nrd, nwr, data_in, data_out, wait_out,
|
|
avm_clk, avm_reset, avm_addr, avm_rd, avm_rdvalid, avm_rdata, avm_wr, avm_wdata, avm_wait
|
|
);
|
|
|
|
///////////////////////////////////////////////////////
|
|
// Pins //
|
|
///////////////////////////////////////////////////////
|
|
|
|
// external signal
|
|
input[31:0] addr;
|
|
input ale;
|
|
input ncs;
|
|
input nrd;
|
|
input nwr;
|
|
input[15:0] data_in;
|
|
output[15:0] data_out;
|
|
output wait_out;
|
|
|
|
// io master
|
|
input avm_clk;
|
|
input avm_reset;
|
|
output[31:0] avm_addr;
|
|
output avm_rd;
|
|
input[15:0] avm_rdata;
|
|
input avm_rdvalid;
|
|
output avm_wr;
|
|
output[15:0] avm_wdata;
|
|
input avm_wait;
|
|
|
|
///////////////////////////////////////////////////////
|
|
// input sync //
|
|
///////////////////////////////////////////////////////
|
|
|
|
reg ncs_s0, ncs_s1, ncs_s2, ncs_s3, ncs_s4;
|
|
|
|
always @(posedge avm_clk)
|
|
begin
|
|
ncs_s0 <= ncs;
|
|
ncs_s1 <= ncs_s0;
|
|
ncs_s2 <= ncs_s1;
|
|
ncs_s3 <= ncs_s2;
|
|
ncs_s4 <= ncs_s3;
|
|
end
|
|
|
|
wire rd_start = (ncs_s2==1 && ncs_s1==0 && nrd==0);
|
|
wire wr_start = (ncs_s4==1 && ncs_s3==0 && nwr==0);
|
|
|
|
///////////////////////////////////////////////////////
|
|
// master read //
|
|
///////////////////////////////////////////////////////
|
|
|
|
reg[2:0] mstate;
|
|
reg avm_rd;
|
|
reg avm_wr;
|
|
reg emm_wait;
|
|
reg cs_wait;
|
|
reg[15:0] avm_wdata;
|
|
reg[31:0] avm_addr;
|
|
reg[15:0] data_out;
|
|
|
|
localparam M_IDLE=0, M_READ=1, M_READ_DATA=2, M_READ_END=3, M_WRITE=4, M_WRITE_END=5;
|
|
|
|
always @(posedge avm_reset or posedge avm_clk)
|
|
begin
|
|
if(avm_reset==1) begin
|
|
mstate <= M_IDLE;
|
|
end else begin
|
|
case(mstate)
|
|
M_IDLE: begin
|
|
if(rd_start==1) begin
|
|
mstate <= M_READ;
|
|
avm_rd <= 1;
|
|
emm_wait <= 1;
|
|
end else if(wr_start==1) begin
|
|
mstate <= M_WRITE;
|
|
avm_wr <= 1;
|
|
emm_wait <= 1;
|
|
end else begin
|
|
avm_rd <= 0;
|
|
avm_wr <= 0;
|
|
emm_wait <= 0;
|
|
mstate <= M_IDLE;
|
|
end
|
|
end
|
|
|
|
M_READ: begin
|
|
if(avm_wait==0) begin
|
|
mstate <= M_READ_DATA;
|
|
avm_rd <= 0;
|
|
end
|
|
end
|
|
M_READ_DATA: begin
|
|
if(avm_rdvalid==1) begin
|
|
emm_wait <= 0;
|
|
mstate <= M_IDLE;
|
|
end
|
|
end
|
|
|
|
M_WRITE: begin
|
|
if(avm_wait==0) begin
|
|
emm_wait <= 0;
|
|
avm_wr <= 0;
|
|
mstate <= M_IDLE;
|
|
end
|
|
end
|
|
|
|
default: begin
|
|
mstate <= M_IDLE;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
always @(posedge emm_wait or negedge ncs)
|
|
begin
|
|
if(emm_wait==1)
|
|
cs_wait <= 0;
|
|
else
|
|
cs_wait <= 1;
|
|
end
|
|
|
|
always @(posedge avm_clk)
|
|
begin
|
|
if(avm_rdvalid==1)
|
|
data_out <= avm_rdata;
|
|
end
|
|
|
|
always @(posedge avm_clk)
|
|
begin
|
|
if(wr_start==1)
|
|
avm_wdata <= data_in;
|
|
end
|
|
|
|
always @(posedge avm_clk)
|
|
begin
|
|
if(wr_start==1 || rd_start==1)
|
|
avm_addr <= addr;
|
|
end
|
|
|
|
assign wait_out = ~(cs_wait | emm_wait);
|
|
|
|
endmodule
|
|
|