это не правильный матрас. правильный вот.
Profi must live!
Моё железо...
1. Profi 5.06/1Mb(DRAM)+Profi5.06(UP)/HDD/3`5FDD/CF512Mb/SD-CARD
3. Profi 6.2 Rev. B/1Mb/3`5FDD/HDD3.2Gb
4. Profi 5.05(down)/1Mb+Profi 5.03(UP)/Pentagon_Fix
Все укомплектованы:
Profi_ZX-BUS/ZXMC2/NemoIDE/SounDrive[свернуть]
Ссылка на Telegram-канал поддержки пользователей Profi.
Короче тот матрас был фигня, это походу не работало что-то из ОЗУ/ПЗУ/Z80
Есть небольшие успехи, тест48 запустился, бордюр весело прыгает, на экране пока что хрень, но более менее статическая, т.е. регенерация DRAM идет нормально, но буферы пока что как-то коряво работают, буду дальше ковыряться...
Переписал большую часть на Verilog.. выбор RAM/ROM пока что не получается на нем сделать.
У меня уже начинает складываться впечатления, что я первый делаю клон на CPLD/FPGA на DRAM, куда не посмотри - все на SRAM делают...
--------- я первый делаю клон на CPLD/FPGA на DRAM
Reverse U16 тоже на динамической памяти.
Но там отдельный модуль занимается памятью - регенерация, управлением банками, простым кэшированием.
Выбор ПЗУ может так:
assign nROMSEL = A15 | A14 | nRD;
Другие комбинации адресов и nMREQ для ОЗУ.
Последний раз редактировалось Копейкин; 01.04.2017 в 07:56.
Только вот такая конструкция заработала для экрана, в схемном виде и в другом ни в какую не хотело работать
Код:reg [7:0] ATTR = 7; reg [7:0] SHIFT_REG = 0; // latch attributes always @(posedge DC2) ATTR <= MD; // latch pixels, pixel shift always @(negedge OSC) if(DC2n & DC1 & DC0) SHIFT_REG <= MD; else SHIFT_REG <= SHIFT_REG << 1; // если написать SHIFT_REG = pixel_latch ? MD : SHIFT_REG << 1; - не работает!
Последний раз редактировалось EvgenRU; 02.04.2017 в 14:49.
... что и неудивительно, потому, что SHIFT_REG - регистр, а регистр должен тактироваться. :-)
Также нежелательно использовать для регистров блокирующее присвоение. ( "=" вместо "<=" )
З.Ы.
Нарезал шилд с процессором, пожалуй тоже что-нибудь сделаю.
Одна беда - нечем зашить ПЗУшку... ну эт что-нибудь придумаю.
EvgenRU, а ты покажи пример схемного ввода и я покажу твои косяки.
Ну, я взял из стандартной схемы кворума
Удалось даже немного упростить
Я тут почитал http://asdasd.rpg.fi/~svo/verilog/assignments/ и как-то уже не на 100% уверен в этом, т.к. синтезатор всё-равно сам всё сделает в этом случае.Код:// latch pixels, pixel shift always @(negedge OSC) if(DC2n & DC1 & DC0) SHIFT_REG <= 202;//MD; else SHIFT_REG <= SHIFT_REG << 1;
PS: ПЗУ могу помочь зашить или подарить зашитое, при желании.
PS2: вот еще мультиплексор РАБОЧИЙ!
Скрытый текст
Код:module ZX_mux( input wire [4:0] H, // horizontal counter input wire [7:0] V, // vertical counter input wire [19:14] RAM, // Muxed Extended RAM address input wire [15:0] A, // Z80 adderss input wire S0, // RAS input wire DC1, // H1 input wire DC2, // H2 input wire SCR, // Second SCREEN (128k) input wire CLK, // CLOCK signal 14MHZ output reg [9:0] MA ); always @(negedge CLK) begin //----------------------- // S0 - RAS // DC1 - 0=CPU/1=VIDEO // DC2 - 0=PIXELS/1=ATTR //----------------------- if(DC1) begin // VIDEO CONTROLLER ADDRESSES // screen area address + DRAM refresh if(S0) begin // SELECT B // screen area row address MA[0] <= 1; MA[1] <= 1; MA[2] <= 0; if(DC2) begin // Attributes MA[3] <= 0; MA[4] <= 1; MA[5] <= 1; end else begin // pixels MA[3] <= V[2]; MA[4] <= V[6]; MA[5] <= V[7]; end MA[6] <= 0; MA[7] <= 0;//SCR; MA[8] <= 0; MA[9] <= 0; end else begin // SELECT A // screen area column address MA[4:0] <= H[4:0]; MA[7:5] <= V[5:3]; if(DC2) begin // attributes MA[8] <= V[6]; MA[9] <= V[7]; end else begin //pixels MA[8] <= V[0]; MA[9] <= V[1]; end end end else begin // CPU ADDRESSES // memory address if(S0) begin // SELECT B // memory row address MA[0] <= RAM[14]; MA[1] <= RAM[16]; MA[2] <= RAM[18]; MA[6:3] <= A[13:10]; MA[7] <= RAM[15]; MA[8] <= RAM[17]; MA[8] <= RAM[19]; end else begin // SELECT A // memory column address MA[9:0] <= A[9:0]; end end end endmodule[свернуть]
PS3: вот еще буферы
Скрытый текст
Код:module ZX_buf( input RAMWEn, input RAMCSn, input DC0, input DC1n, inout [7:0] D, inout [7:0] MD ); reg [7:0] wr_buf; wire wrbuf = DC0 & DC1n; assign MD = RAMWEn ? 8'bZZZZZZZZ : D; assign D = RAMCSn ? 8'bZZZZZZZZ : wr_buf; always @ (posedge wrbuf) wr_buf <= MD; endmodule[свернуть]
Последний раз редактировалось EvgenRU; 02.04.2017 в 17:13.
Зачем непонятная и сложная 299, когда есть православная 198 (ИР13)? Я понимаю, что синтезатор вырежет из нее тристэйт, но зачем усложнять то? И вообще, зачем использовать сложный элемент в кастрированном режиме, если синтезатор все равно его обкромсает, причем часто не так, как нужно вам? Если вам нужно только 2 режима: загрузка и сдвиг, то не проще ли синтезатору прямо об этом сказать?
Откройте уже для себя просмотр RTL. Это единственный способ узнать, как именно поняли вас синтезатор и фиттер (а они работают вместе и результат часто отличается для разных типов ПЛИС).
Потому, что этот мультиплексор регистровый (с хранением результата) и управляется из одного always блока, что как раз и соответствует всем требованиям. Если бы вам нужен был мультплекор на комбинаторике, его синтаксис был бы несколько иначе. Вот пример:
Скрытый текст
Код:assign MAPC_A[17:10] = (~CTRL[7]) ? ( (PPU_A[12:11] == 2'h0) ? BCH0[7:0] : (PPU_A[12:11] == 2'h1) ? BCH1[7:0] : (PPU_A[12:10] == 3'h4) ? CHR2[7:0] : (PPU_A[12:10] == 3'h5) ? CHR3[7:0] : (PPU_A[12:10] == 3'h6) ? CHR4[7:0] : CHR5[7:0] ) : ( (PPU_A[12:10] == 3'h0) ? CHR2[7:0] : (PPU_A[12:10] == 3'h1) ? CHR3[7:0] : (PPU_A[12:10] == 3'h2) ? CHR4[7:0] : (PPU_A[12:10] == 3'h3) ? CHR5[7:0] : (PPU_A[12:11] == 2'h2) ? BCH0[7:0] : BCH1[7:0] );[свернуть]
Последний раз редактировалось HardWareMan; 02.04.2017 в 12:40.
Ну и для полноты картины генератор клока без лишних регистров, который использую сейчас
Скрытый текст
Код:module ZX_clock_gen( input wire CLK, // 14 MHz clock input input wire M1n, input wire IORQn, input wire RESn, output reg PIXCLK = 0, output wire PIXCLKn, output wire DC0, output wire DC0n, output wire DC1, output wire DC1n, output wire DC2, output wire DC2n, output wire [4:0] H, output wire [7:0] V, output wire HSYN, output wire VSYN, output wire BORD, output wire BLANCn, output wire INTn, output wire SYNn, output wire CASn, output reg RASn = 1, output wire RAS ); parameter HBorderStart = 256; // X resolution parameter HBlancStart = 320; parameter HBlancEnd = 384; parameter HSynStart = 320; parameter HSynEnd = 352; parameter HLineEnd = 448; parameter VBorderStart = 192; // Y Resolution parameter VBlancStart = 248; parameter VBlancEnd = 256; parameter VSynStart = 248; parameter VSynEnd = 256; parameter VIntStart = 256; parameter VIntEnd = 264; parameter VLineEnd = 320; reg [8:0] cntH = 0; reg [8:0] cntV = 0; reg CAS = 0; always @(negedge CLK) begin PIXCLK <= ~PIXCLK; CAS <= cntH[0]; end always @(negedge PIXCLK)// or negedge RESn) begin cntH <= cntH + 1'b1; RASn <= cntH[0]; if(cntH + 1'b1 == HLineEnd) // should be cntH + 1 as it is non blocking! begin cntH <= 9'b000000000; cntV <= cntV + 1'b1; if(cntV + 1'b1 == VLineEnd) // should be cntV + 1 as it is non blocking! cntV <= 9'b000000000; end end wire HBR = (cntH >= HBorderStart) ? 1'b1 : 1'b0; wire VBR = (cntV >= VBorderStart) ? 1'b1 : 1'b0; wire HBL = (cntH >= HBlancStart && cntH <= HBlancEnd ) ? 1'b1 : 1'b0; wire VBL = (cntV >= VBlancStart && cntV <= VBlancEnd ) ? 1'b1 : 1'b0; assign HSYN = (cntH >= HSynStart && cntH <= HSynEnd ) ? 1'b1 : 1'b0; assign VSYN = (cntV >= VSynStart && cntV <= VSynEnd ) ? 1'b1 : 1'b0; assign INTn = (cntV >= VIntStart && cntV <= VIntEnd ) ? 1'b0 : 1'b1; assign PIXCLKn = PIXCLK; assign DC0 = cntH[0]; assign DC0n = ~cntH[0]; assign DC1 = cntH[1]; assign DC1n = ~cntH[1]; assign DC2 = cntH[2]; assign DC2n = ~cntH[2]; assign H[4:0] = cntH[7:3]; assign V[7:0] = cntV[7:0]; assign BLANCn = ~(VBL | HBL); assign SYNn = ~(HSYN ^ VSYN); assign BORD = VBR | HBR; assign CASn = ~CAS; assign RAS = ~RASn; endmodule[свернуть]
Гляньте, может еще остались какие косяки...
Последний раз редактировалось EvgenRU; 02.04.2017 в 11:46.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)