mirror of
https://github.com/UzixLS/TSConf_MiST.git
synced 2025-07-19 07:11:22 +03:00
first somehow working version for MIST
This commit is contained in:
@ -49,7 +49,7 @@
|
||||
// - DMA - CPU
|
||||
|
||||
|
||||
module arbiter
|
||||
module arbiter
|
||||
(
|
||||
|
||||
input clk,
|
||||
@ -57,16 +57,17 @@ module arbiter
|
||||
input c1,
|
||||
input c2,
|
||||
input c3,
|
||||
input cyc,
|
||||
|
||||
// dram.v interface
|
||||
output [20:0] dram_addr, // address for dram access
|
||||
output [21:0] dram_addr, // address for dram access
|
||||
output dram_req, // dram request
|
||||
output dram_rnw, // Read-NotWrite
|
||||
output [ 1:0] dram_bsel, // byte select: bsel[1] for wrdata[15:8], bsel[0] for wrdata[7:0]
|
||||
output [15:0] dram_wrdata, // data to be written
|
||||
|
||||
// video
|
||||
input [20:0] video_addr, // during access block, only when video_strobe==1
|
||||
input [20:0] video_addr, // during access block, only when video_strobe==1
|
||||
input go, // start video access blocks
|
||||
input [ 4:0] video_bw, // [4:3] - total cycles: 11 = 8 / 01 = 4 / 00 = 2
|
||||
// [2:0] - need cycles
|
||||
@ -77,65 +78,77 @@ module arbiter
|
||||
output next_vid, // used for TM prefetch
|
||||
|
||||
// CPU
|
||||
input [20:0] cpu_addr,
|
||||
input [20:0] cpu_addr,
|
||||
input [ 7:0] cpu_wrdata,
|
||||
input cpu_req,
|
||||
input cpu_rnw,
|
||||
input cpu_csrom,
|
||||
input cpu_wrbsel,
|
||||
output reg cpu_next, // next cycle is allowed to be used by CPU
|
||||
output reg cpu_strobe, // c2 strobe
|
||||
output reg cpu_latch, // c2-c3 strobe
|
||||
output curr_cpu_o,
|
||||
|
||||
// DMA
|
||||
input [20:0] dma_addr,
|
||||
input [20:0] dma_addr,
|
||||
input [15:0] dma_wrdata,
|
||||
input dma_req,
|
||||
input dma_rnw,
|
||||
output dma_next,
|
||||
|
||||
// TS
|
||||
input [20:0] ts_addr,
|
||||
input [20:0] ts_addr,
|
||||
input ts_req,
|
||||
output ts_pre_next,
|
||||
output ts_next,
|
||||
|
||||
// TM
|
||||
input [20:0] tm_addr,
|
||||
input tm_req,
|
||||
output tm_next
|
||||
input [20:0] tm_addr,
|
||||
input tm_req,
|
||||
output tm_next,
|
||||
|
||||
// ROM loader
|
||||
input loader_clk,
|
||||
input [15:0] loader_addr,
|
||||
input [7:0] loader_data,
|
||||
input loader_wr
|
||||
);
|
||||
|
||||
assign curr_cpu_o = curr_cpu;
|
||||
|
||||
localparam CYCLES = 5;
|
||||
localparam CYCLES = 6;
|
||||
|
||||
localparam CYC_CPU = 5'b00001;
|
||||
localparam CYC_VID = 5'b00010;
|
||||
localparam CYC_TS = 5'b00100;
|
||||
localparam CYC_TM = 5'b01000;
|
||||
localparam CYC_DMA = 5'b10000;
|
||||
localparam CYC_FREE = 5'b00000;
|
||||
localparam CYC_CPU = 6'b000001;
|
||||
localparam CYC_VID = 6'b000010;
|
||||
localparam CYC_TS = 6'b000100;
|
||||
localparam CYC_TM = 6'b001000;
|
||||
localparam CYC_DMA = 6'b010000;
|
||||
localparam CYC_LOADER = 6'b100000;
|
||||
localparam CYC_FREE = 6'b000000;
|
||||
|
||||
localparam CPU = 0;
|
||||
localparam VIDEO = 1;
|
||||
localparam TS = 2;
|
||||
localparam TM = 3;
|
||||
localparam DMA = 4;
|
||||
localparam CPU = 0;
|
||||
localparam VIDEO = 1;
|
||||
localparam TS = 2;
|
||||
localparam TM = 3;
|
||||
localparam DMA = 4;
|
||||
localparam LOADER = 5;
|
||||
|
||||
reg [CYCLES-1:0] curr_cycle; // type of the cycle in progress
|
||||
reg [CYCLES-1:0] next_cycle; // type of the next cycle
|
||||
|
||||
wire next_cpu = next_cycle[CPU];
|
||||
assign next_vid = next_cycle[VIDEO];
|
||||
wire next_ts = next_cycle[TS];
|
||||
wire next_tm = next_cycle[TM];
|
||||
wire next_dma = next_cycle[DMA];
|
||||
wire next_cpu = next_cycle[CPU];
|
||||
assign next_vid = next_cycle[VIDEO];
|
||||
wire next_ts = next_cycle[TS];
|
||||
wire next_tm = next_cycle[TM];
|
||||
wire next_dma = next_cycle[DMA];
|
||||
wire next_loader = next_cycle[LOADER];
|
||||
|
||||
wire curr_cpu = curr_cycle[CPU];
|
||||
wire curr_vid = curr_cycle[VIDEO];
|
||||
wire curr_ts = curr_cycle[TS];
|
||||
wire curr_tm = curr_cycle[TM];
|
||||
wire curr_dma = curr_cycle[DMA];
|
||||
wire curr_cpu = curr_cycle[CPU];
|
||||
wire curr_vid = curr_cycle[VIDEO];
|
||||
wire curr_ts = curr_cycle[TS];
|
||||
wire curr_tm = curr_cycle[TM];
|
||||
wire curr_dma = curr_cycle[DMA];
|
||||
wire curr_loader = curr_cycle[LOADER];
|
||||
|
||||
|
||||
// track blk_rem counter:
|
||||
@ -148,11 +161,11 @@ wire video_idle = ~|vid_rem;
|
||||
|
||||
reg [2:0] blk_rem; // remaining accesses in a block (7..0)
|
||||
reg stall;
|
||||
always @(posedge clk) begin
|
||||
always @(posedge clk) begin
|
||||
if (c3) begin
|
||||
blk_rem <= blk_nrem;
|
||||
if (video_start) stall <= bw_full & go;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -167,6 +180,18 @@ reg [2:0] vid_rem; // remaining video accesses in block
|
||||
always @(posedge clk) if (c3) vid_rem <= vid_nrem;
|
||||
|
||||
|
||||
reg loader_wr0;
|
||||
reg [7:0] loader_data0;
|
||||
always @(posedge loader_clk) begin
|
||||
if (loader_wr) begin
|
||||
loader_wr0 <= 1'd1;
|
||||
loader_data0 <= loader_data;
|
||||
end
|
||||
else if (cyc) begin
|
||||
loader_wr0 <= 1'd0;
|
||||
end
|
||||
end
|
||||
|
||||
// next cycle decision
|
||||
wire [CYCLES-1:0] cyc_dev = tm_req ? CYC_TM : (ts_req ? CYC_TS : CYC_DMA);
|
||||
wire dev_req = ts_req || tm_req || dma_req;
|
||||
@ -174,7 +199,11 @@ wire dev_req = ts_req || tm_req || dma_req;
|
||||
wire dev_over_cpu = 0;
|
||||
|
||||
always @* begin
|
||||
if (video_start) begin // video burst start
|
||||
if (loader_wr0) begin
|
||||
cpu_next = 1'b0;
|
||||
next_cycle = CYC_LOADER;
|
||||
end
|
||||
else if (video_start) begin // video burst start
|
||||
if (go) begin // video active line - 38us-ON, 26us-ON
|
||||
cpu_next = dev_over_cpu ? 1'b0 : !bw_full;
|
||||
next_cycle = dev_over_cpu ? CYC_VID : (bw_full ? CYC_VID : (cpu_req ? CYC_CPU : CYC_VID));
|
||||
@ -182,26 +211,27 @@ always @* begin
|
||||
else begin // video idle
|
||||
cpu_next = !dev_over_cpu;
|
||||
next_cycle = dev_over_cpu ? cyc_dev : (cpu_req ? CYC_CPU : (dev_req ? cyc_dev : CYC_FREE));
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin // video burst in progress
|
||||
cpu_next = dev_over_cpu ? 1'b0 : !video_only;
|
||||
next_cycle = video_only ? CYC_VID : (dev_over_cpu ? cyc_dev : (cpu_req ? CYC_CPU : (!video_idle ? CYC_VID : (dev_req ? cyc_dev : CYC_FREE))));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) if (c3) curr_cycle <= next_cycle;
|
||||
always @(posedge clk) if (c3) curr_cycle <= next_cycle;
|
||||
|
||||
// DRAM interface
|
||||
assign dram_wrdata= curr_dma ? dma_wrdata : {cpu_wrdata,cpu_wrdata}; // write data has to be clocked at c0 in dram.v
|
||||
assign dram_bsel = {cpu_wrbsel | next_dma, ~cpu_wrbsel | next_dma};
|
||||
assign dram_wrdata= curr_loader? {loader_data0,loader_data0} : curr_dma ? dma_wrdata : {cpu_wrdata,cpu_wrdata}; // write data has to be clocked at c0 in dram.v
|
||||
assign dram_bsel = next_loader? {loader_addr[0], ~loader_addr[0]} : next_dma ? 2'b11 : {cpu_wrbsel, ~cpu_wrbsel};
|
||||
assign dram_req = |next_cycle;
|
||||
assign dram_rnw = next_cpu ? cpu_rnw : ~next_dma | dma_rnw;
|
||||
assign dram_addr = {21{next_cpu}} & cpu_addr
|
||||
| {21{next_vid}} & video_addr
|
||||
| {21{next_ts }} & ts_addr
|
||||
| {21{next_tm }} & tm_addr
|
||||
| {21{next_dma}} & dma_addr;
|
||||
assign dram_rnw = next_loader? 1'b0 : next_cpu ? cpu_rnw : ~next_dma | dma_rnw;
|
||||
assign dram_addr = {22{next_loader}} & { 1'b1, 6'b000000, loader_addr[15:1] }
|
||||
| {22{next_cpu}} & { cpu_csrom, {6{~cpu_csrom}} & cpu_addr[20:15], cpu_addr[14:0] }
|
||||
| {22{next_vid}} & { 1'b0, video_addr }
|
||||
| {22{next_ts }} & { 1'b0, ts_addr }
|
||||
| {22{next_tm }} & { 1'b0, tm_addr }
|
||||
| {22{next_dma}} & { 1'b0, dma_addr };
|
||||
|
||||
reg cpu_rnw_r;
|
||||
always @(posedge clk) if (c3) cpu_rnw_r <= cpu_rnw;
|
||||
|
@ -1,124 +0,0 @@
|
||||
//
|
||||
// ddram.v
|
||||
//
|
||||
// DE10-nano DDR3 memory interface
|
||||
//
|
||||
// Copyright (c) 2017 Sorgelig
|
||||
//
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ------------------------------------------
|
||||
//
|
||||
|
||||
// 8-bit version
|
||||
|
||||
module ddram
|
||||
(
|
||||
input reset,
|
||||
input DDRAM_CLK,
|
||||
|
||||
input DDRAM_BUSY,
|
||||
output [7:0] DDRAM_BURSTCNT,
|
||||
output [28:0] DDRAM_ADDR,
|
||||
input [63:0] DDRAM_DOUT,
|
||||
input DDRAM_DOUT_READY,
|
||||
output DDRAM_RD,
|
||||
output [63:0] DDRAM_DIN,
|
||||
output [7:0] DDRAM_BE,
|
||||
output DDRAM_WE,
|
||||
|
||||
input [27:0] addr, // 256MB at the end of 1GB
|
||||
output [7:0] dout, // data output to cpu
|
||||
input [7:0] din, // data input from cpu
|
||||
input we, // cpu requests write
|
||||
input rd, // cpu requests read
|
||||
output ready // dout is valid. Ready to accept new read/write.
|
||||
);
|
||||
|
||||
assign DDRAM_BURSTCNT = 1;
|
||||
assign DDRAM_BE = (8'd1<<ram_address[2:0]) | {8{ram_read}};
|
||||
assign DDRAM_ADDR = {4'b0011, ram_address[27:3]}; // RAM at 0x30000000
|
||||
assign DDRAM_RD = ram_read;
|
||||
assign DDRAM_DIN = ram_cache;
|
||||
assign DDRAM_WE = ram_write;
|
||||
|
||||
assign dout = ram_q;
|
||||
assign ready = ~busy;
|
||||
|
||||
reg [7:0] ram_q;
|
||||
reg [27:0] ram_address;
|
||||
reg ram_read;
|
||||
reg [63:0] ram_cache;
|
||||
reg ram_write;
|
||||
reg [7:0] cached;
|
||||
reg busy;
|
||||
|
||||
|
||||
always @(posedge DDRAM_CLK)
|
||||
begin
|
||||
reg old_rd, old_we;
|
||||
reg old_reset;
|
||||
reg state;
|
||||
|
||||
old_reset <= reset;
|
||||
if(old_reset && ~reset) begin
|
||||
busy <= 0;
|
||||
state <= 0;
|
||||
cached <= 0;
|
||||
end
|
||||
|
||||
if(!DDRAM_BUSY)
|
||||
begin
|
||||
ram_write <= 0;
|
||||
ram_read <= 0;
|
||||
if(state) begin
|
||||
if(DDRAM_DOUT_READY) begin
|
||||
ram_q <= DDRAM_DOUT[{ram_address[2:0], 3'b000} +:8];
|
||||
ram_cache <= DDRAM_DOUT;
|
||||
cached <= 8'hFF;
|
||||
state <= 0;
|
||||
busy <= 0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
old_rd <= rd;
|
||||
old_we <= we;
|
||||
busy <= 0;
|
||||
|
||||
if(~old_we && we) begin
|
||||
ram_cache[{addr[2:0], 3'b000} +:8] <= din;
|
||||
ram_address <= addr;
|
||||
busy <= 1;
|
||||
ram_write <= 1;
|
||||
cached <= ((ram_address[27:3] == addr[27:3]) ? cached : 8'h00) | (8'd1<<addr[2:0]);
|
||||
end
|
||||
|
||||
if(~old_rd && rd) begin
|
||||
if((ram_address[27:3] == addr[27:3]) && (cached & (8'd1<<addr[2:0]))) begin
|
||||
ram_q <= ram_cache[{addr[2:0], 3'b000} +:8];
|
||||
end
|
||||
else begin
|
||||
ram_address <= addr;
|
||||
ram_read <= 1;
|
||||
state <= 1;
|
||||
cached <= 0;
|
||||
busy <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -56,7 +56,7 @@ defparam
|
||||
altsyncram_component.clock_enable_input_b = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_b = "BYPASS",
|
||||
altsyncram_component.intended_device_family = "Cyclone V",
|
||||
altsyncram_component.intended_device_family = "Cyclone III",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
|
||||
altsyncram_component.outdata_aclr_a = "NONE",
|
||||
|
@ -128,7 +128,7 @@ assign SDRAM_DQMH = SDRAM_A[12];
|
||||
altddio_out
|
||||
#(
|
||||
.extend_oe_disable("OFF"),
|
||||
.intended_device_family("Cyclone V"),
|
||||
.intended_device_family("Cyclone III"),
|
||||
.invert_output("OFF"),
|
||||
.lpm_hint("UNUSED"),
|
||||
.lpm_type("altddio_out"),
|
||||
|
Reference in New Issue
Block a user