рдЕрдЬрдЧрд░ рдФрд░ FPGAред рдкрд░реАрдХреНрд╖рдг

рдкрд╣рд▓реЗ рд▓реЗрдЦ рдХреА рдирд┐рд░рдВрддрд░рддрд╛ рдореЗрдВ, рдореИрдВ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдЬрдЧрд░ рдореЗрдВ FPGA (FPGA) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдпрд╣ рдЖрд▓реЗрдЦ рдкрд░реАрдХреНрд╖рдг рдкрд╣рд▓реВ рдХреЛ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдХрд╡рд░ рдХрд░реЗрдЧрд╛ред рдпрджрд┐ FHDA рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП MyHDL рдлреНрд░реЗрдорд╡рд░реНрдХ рд▓реЛрдЧреЛрдВ рдХреЛ рдкрд░рд┐рдЪрд┐рдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рдФрд░ рдЗрдХреЛрд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдЬрдЧрд░ рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рддреЛ рдЕрдиреБрднрд╡реА FPGA рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЕрдЬрдЧрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдЕрд░реНрде рдирд╣реАрдВ рд╕рдордЭрддреЗ рд╣реИрдВред MyHDL рдФрд░ рд╡реЗрд░рд┐рд▓реЙрдЧ рдХреЗ рд▓рд┐рдП рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рд╡рд┐рд╡рд░рдг рдкреНрд░рддрд┐рдорд╛рди рд╕рдорд╛рди рд╣реИрдВ, рдФрд░ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрд╛рд╖рд╛ рдЪреБрдирдирд╛ рдЖрджрдд рдФрд░ рд╕реНрд╡рд╛рдж рдХрд╛ рд╡рд┐рд╖рдп рд╣реИред рд╡реЗрд░рд┐рд▓реЛрдЧ / рд╡реАрдПрдЪрдбреАрдПрд▓ рдЗрд╕ рддрдереНрдп рдХреЗ рд▓рд┐рдП рдЦрдбрд╝рд╛ рд╣реИ рдХрд┐ рдлрд░реНрдорд╡реЗрдпрд░ рдЗрди рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡реЗ рдбрд┐рдЬрд┐рдЯрд▓ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рд╣реИрдВред рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдиреМрд╕рд┐рдЦрд┐рдП рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рдпрдерди, рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рд▓рд┐рдЦрдиреЗ рдореЗрдВ рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИред FPGA рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд╕рдордп рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рдЙрдирдХреЗ рдбрд┐рдЬрд╛рдЗрдиреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдореЗрдВ рдмрд┐рддрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдЧрд▓рд╛, рдореИрдВ рдЙрджрд╛рд╣рд░рдг рдХреЗ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ MyHDL рдХреЗ рд╕рд╛рде рдЕрдЬрдЧрд░ рдореЗрдВ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ FPGA рдкрд░ рдореЗрдореЛрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдХ рдЙрдкрдХрд░рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдп рд╣реИред рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рдореИрдВ рдПрдХ рд╕рдорд╛рдВрддрд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдиреНрдп рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдореЗрдореЛрд░реА (рдФрд░ рдПрдХ рд╕реАрд░рд┐рдпрд▓ рдПрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП 22C рдХреЗ рд▓рд┐рдП рд▓реЗ рдЬрд╛рдКрдВрдЧрд╛)ред рдЗрд╕ рддрд░рд╣ рдХреЗ microcircuits рд╣рдореЗрд╢рд╛ рдЗрд╕ рддрдереНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ рдХрд┐ рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдкрд┐рдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рджреВрд╕рд░реА рддрд░рдл, рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рддреЗрдЬрд╝ рдФрд░ рдЖрд╕рд╛рди рд╡рд┐рдирд┐рдордп рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдШрд░реЗрд▓реВ 1645RU1U рдФрд░ рдЗрд╕рдХреЗ рдПрдирд╛рд▓реЙрдЧред



рдореЙрдбреНрдпреВрд▓ рд╡рд┐рд╡рд░рдг


рд░рд┐рдХреЙрд░реНрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ: FPGA 16-рдмрд┐рдЯ рд╕реЗрд▓ рдПрдбреНрд░реЗрд╕, 8-рдмрд┐рдЯ рдбреЗрдЯрд╛ рджреЗрддрд╛ рд╣реИ, рдПрдХ рд░рд╛рдЗрдЯ рд╕рд┐рдЧреНрдирд▓ WE (рд░рд╛рдЗрдЯ рд╕рдХреНрд╖рдо) рд▓рд┐рдЦрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ OE (рдЖрдЙрдЯрдкреБрдЯ рдЗрдиреЗрдмрд▓) рдФрд░ CE (рдЪрд┐рдк рдЗрдиреЗрдмрд▓реНрдб) рд╣рдореЗрд╢рд╛ рд╕рдХреНрд╖рдо рд╣реЛрддреЗ рд╣реИрдВ, рд░реАрдбрд┐рдВрдЧ рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм рд╕реЗрд▓ рдПрдбреНрд░реЗрд╕ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдЦрди рдФрд░ рдкрдврд╝рдирд╛ рджреЛрдиреЛрдВ рдХреЛ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдХрдИ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ adr_start рдкрддреЗ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ adr_write рд╕рд┐рдЧреНрдирд▓ рдХреЗ рдЕрдЧреНрд░рдгреА рдХрд┐рдирд╛рд░реЗ рдкрд░ рджрд░реНрдЬ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдПрдХ рд╕реЗрд▓ рдПрдХ рдордирдорд╛рдиреЗ рдкрддреЗ (рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЕрднрд┐рдЧрдо) рдкрд░ рд╣реЛрддрд╛ рд╣реИред

MyHDL рдкрд░, рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ (рд░рд┐рд╡рд░реНрд╕ рд▓реЙрдЬрд┐рдХ рдореЗрдВ рд╕рд┐рдЧреНрдирд▓ рд▓рд┐рдЦрддреЗ рдФрд░ рдкрдврд╝рддреЗ рд╣реИрдВ):

from myhdl import * @block def ram_driver(data_in, data_out, adr, adr_start, adr_write, data_memory, read, write, we): #     mem_z = data_memory.driver() #      @always(adr_write.posedge, write.posedge, read.negedge) def write_start_adr(): if adr_write: #    adr.next = adr_start else: #    / adr.next = adr + 1 @always(write) def write_data(): if not write: mem_z.next = data_in we.next = 0 #    ,    else: mem_z.next = None #        data_out.next = data_memory we.next = 1 return write_data, write_start_adr 

рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡реЗрд░рд┐рд▓реЙрдЧ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 def convert(hdl): data_memory = TristateSignal(intbv(0)[8:]) data_in = Signal(intbv(0)[8:]) data_out = Signal(intbv(0)[8:]) adr = Signal(intbv(0)[16:]) adr_start = Signal(intbv(0)[16:]) adr_write = Signal(bool(0)) read, write, we = [Signal(bool(1)) for i in range(3)] inst = ram_driver(data_in, data_out, adr, adr_start, adr_write, data_memory, read, write, we) inst.convert(hdl=hdl) convert(hdl='Verilog') 

рдлрд┐рд░ рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓рддреЗ рд╣реИрдВ:
 `timescale 1ns/10ps module ram_driver ( data_in, data_out, adr, adr_start, adr_write, data_memory, read, write, we ); input [7:0] data_in; output [7:0] data_out; reg [7:0] data_out; output [15:0] adr; reg [15:0] adr; input [15:0] adr_start; input adr_write; inout [7:0] data_memory; wire [7:0] data_memory; input read; input write; output we; reg we; reg [7:0] mem_z; assign data_memory = mem_z; always @(write) begin: RAM_DRIVER_WRITE_DATA if ((!write)) begin mem_z <= data_in; we <= 0; end else begin mem_z <= 'bz; data_out <= data_memory; we <= 1; end end always @(posedge adr_write, posedge write, negedge read) begin: RAM_DRIVER_WRITE_START_ADR if (adr_write) begin adr <= adr_start; end else begin adr <= (adr + 1); end end endmodule 

рд╕рд┐рдореБрд▓реЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд╡реЗрд░рд┐рд▓реЙрдЧ рдореЗрдВ рдмрджрд▓рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдЗрд╕ рдХрджрдо рдХреЛ рдПрдлрдкреАрдЬреАрдП рдХреЛ рдЪрдордХрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред

рдореЛрдбрд▓рд┐рдВрдЧ


рддрд░реНрдХ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рдмрд╛рдж, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдк рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрдирдкреБрдЯ рдкреНрд░рднрд╛рд╡реЛрдВ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдФрд░ рд╕рдордп рдЖрд░реЗрдЦ рдореЗрдВ рдореЙрдбреНрдпреВрд▓ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдПред рд▓реЗрдХрд┐рди рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде, рдореЗрдореЛрд░реА рдЪрд┐рдк рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдореЙрдбреНрдпреВрд▓ рдХреА рдмрд╛рддрдЪреАрдд рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рдирд╛ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реИред рдЗрд╕рд▓рд┐рдП, рдмрдирд╛рдП рдЧрдП рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рдореЗрдореЛрд░реА рдореЙрдбрд▓ рдмрдирд╛рдиреЗ рдФрд░ рдЗрди рджреЛ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рдмреАрдЪ рдмрд╛рддрдЪреАрдд рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЪреВрдВрдХрд┐ рдХрд╛рдо рдЕрдЬрдЧрд░ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рджрд┐рдпрд╛ рдЧрдпрд╛ рд╢рдмреНрджрдХреЛрд╢ (рд╢рдмреНрджрдХреЛрд╢) рдореЗрдореЛрд░реА рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП рдЦреБрдж рдХреЛ рдмрддрд╛рддрд╛ рд╣реИред рд╡рд╣ рдбреЗрдЯрд╛ рдЬрд┐рд╕рдореЗрдВ {рдХреБрдВрдЬреА: рдорд╛рди}, рдФрд░ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП {рдкрддрд╛: рдбреЗрдЯрд╛} рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

 memory = { 0: 123, 1: 456, 2: 789 } memory[0] >> 123 memory[1] >> 456 

рдЗрд╕реА рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП, рд╕реВрдЪреА рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдЙрдкрдпреБрдХреНрдд рд╣реИ, рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рдЕрдкрдиреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╣реИрдВ рдЬреЛ рд╕реВрдЪреА рдореЗрдВ рддрддреНрд╡ рдХреЗ рд╕реНрдерд╛рди рдХреЛ рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВ:

 memory = [123, 456, 789] memory[0] >> 123 memory[1] >> 456 

рдЕрдзрд┐рдХ рджреГрд╢реНрдпрддрд╛ рдХреЗ рдорджреНрджреЗрдирдЬрд░ рд╕реНрдореГрддрд┐ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд▓рдЧрддрд╛ рд╣реИред

рдкрд░реАрдХреНрд╖рдг рд╢реЗрд▓ рдХрд╛ рд╡рд░реНрдгрди (рдлрд╝рд╛рдЗрд▓ test_seq_access.py рдореЗрдВ) рд╕рдВрдХреЗрддреЛрдВ рдХреА рдШреЛрд╖рдгрд╛, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛рдУрдВ рдХреЗ рдЖрд░рдВрдн рдФрд░ рдЙрдирдХреЗ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдореЗрдореЛрд░реА рдбреНрд░рд╛рдЗрд╡рд░ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдлреЗрдВрдХрдиреЗ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ:

 @block def testbench(): data_memory = TristateSignal(intbv(0)[8:]) data_in = Signal(intbv(0)[8:]) data_out = Signal(intbv(0)[8:]) adr = Signal(intbv(0)[16:]) adr_start = Signal(intbv(20)[16:]) adr_write = Signal(bool(0)) read, write, we = [Signal(bool(1)) for i in range(3)] ram = ram_driver(data_in, data_out, adr, adr_start, adr_write, data_memory, read, write, we) 

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЗрдореЛрд░реА рдореЙрдбрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛рдПрдБ рдЖрд░рдореНрднрд┐рдХ рд╣реИрдВ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдореЗрдореЛрд░реА рд╢реВрдиреНрдп рдорд╛рдиреЛрдВ рд╕реЗ рднрд░реА рд╣реЛрддреА рд╣реИред рдореЗрдореЛрд░реА рдореЙрдбрд▓ рдХреЛ 128 рдХреЛрд╢рд┐рдХрд╛рдУрдВ рддрдХ рд╕реАрдорд┐рдд рдХрд░реЗрдВ:

 memory = {i: intbv(0) for i in range(128)} 

рдФрд░ рд╕реНрдореГрддрд┐ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ: рдЬрдм рд╣рдо рдирд┐рдореНрди рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рд╕рдВрдмрдВрдзрд┐рдд рдореЗрдореЛрд░реА рдкрддреЗ рдХреА рдкрдВрдХреНрддрд┐ рдореЗрдВ рдорд╛рди рд▓рд┐рдЦреЗрдВ, рдЕрдиреНрдпрдерд╛ рдореЙрдбрд▓ рджрд┐рдП рдЧрдП рдкрддреЗ рдкрд░ рдореВрд▓реНрдп рджреЗрддрд╛ рд╣реИ:

 mem_z = data_memory.driver() @always_comb def access(): if not we: memory[int(adr.val)] = data_memory.val if we: data_out.next = memory[int(adr.val)] mem_z.next = None 

рдлрд┐рд░, рдПрдХ рд╣реА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдЖрдк рдЗрдирдкреБрдЯ рд╕рдВрдХреЗрддреЛрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЕрдиреБрдХреНрд░рдорд┐рдХ рд▓рд┐рдЦрдиреЗ / рдкрдврд╝рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП): рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкрддрд╛ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ тЖТ 8 рд╕реВрдЪрдирд╛ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ тЖТ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкрддрд╛ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ тЖТ 8 рджрд░реНрдЬ рдХреА рдЧрдИ рд╕реВрдЪрдирд╛ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред

 @instance def stimul(): init_adr = random.randint(0, 50) #   yield delay(100) write.next = 1 adr_write.next = 1 adr_start.next = init_adr #   yield delay(100) adr_write.next = 0 yield delay(100) for i in range(8): # 8    write.next = 0 data_in.next = random.randint(0, 100) yield delay(100) write.next = 1 yield delay(100) adr_start.next = init_adr #   adr_write.next = 1 yield delay(100) adr_write.next = 0 yield delay(100) for i in range(8): #   read.next = 0 yield delay(100) read.next = 1 yield delay(100) raise StopSimulation return stimul, ram, access 

рд╕рд┐рдореБрд▓реЗрд╢рди рдЪрд▓рд╛рдПрдБ:

 tb = testbench() tb.config_sim(trace=True) tb.run_sim() 

рдХрд╛рд░реНрдпрдХреНрд░рдо рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, testbench_seq_access.vcd рдлрд╝рд╛рдЗрд▓ рдХрд╛рд░реНрдп рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ, рдЗрд╕реЗ gtkave рдореЗрдВ рдЦреЛрд▓реЗрдВ:

 gtkwave testbench_seq_access.vcd 

рдФрд░ рд╣рдо рддрд╕реНрд╡реАрд░ рджреЗрдЦрддреЗ рд╣реИрдВ:



рд░рд┐рдХреЙрд░реНрдб рдХреА рдЧрдИ рдЬрд╛рдирдХрд╛рд░реА рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкрдврд╝реА рдЧрдИред

рдЖрдк рдирд┐рдореНрди рдХреЛрдб рдХреЛ testbench рдореЗрдВ рдЬреЛрдбрд╝рдХрд░ рдореЗрдореЛрд░реА рдХреА рд╕рд╛рдордЧреНрд░реА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:

 for key, value in memory.items(): print('adr:{}'.format(key), 'data:{}'.format(value)) 

рдХрдВрд╕реЛрд▓ рдореЗрдВ рдирд┐рдореНрди рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИ:



рдкрд░реАрдХреНрд╖рдг


рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдХрдИ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рдмрдврд╝реА рд╣реБрдИ рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдпреЛрдЧреНрдп / рдкрдардиреАрдп рдХреЛрд╢рд┐рдХрд╛рдПрдБ рд╣реЛрддреА рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдИ рдкрд░реАрдХреНрд╖рдг рдЪрдХреНрд░ рдФрд░ рдбрдореА рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХреЛ рдЯреЗрд╕реНрдЯрдмреЗрдВрдЪ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рд▓рд┐рдЦрд┐рдд рдФрд░ рдкрдардиреАрдп рдЬрд╛рдирдХрд╛рд░реА рдФрд░ рдореБрдЦрд░ рдирд┐рд░реНрдорд╛рдг рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рджреЛ рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рддреНрд░реБрдЯрд┐ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ:

 @instance def stimul(): for time in range(100): temp_mem_write = {} temp_mem_read = {} init_adr = random.randint(0, 50) yield delay(100) write.next = 1 adr_write.next = 1 adr_start.next = init_adr yield delay(100) adr_write.next = 0 yield delay(100) for i in range(64): write.next = 0 data_in.next = random.randint(0, 100) temp_mem_write[i] = int(data_in.next) yield delay(100) write.next = 1 yield delay(100) adr_start.next = init_adr adr_write.next = 1 yield delay(100) adr_write.next = 0 yield delay(100) for i in range(64): read.next = 0 temp_mem_read[i] = int(data_out.val) yield delay(100) read.next = 1 yield delay(100) assert temp_mem_write == temp_mem_read, "   " for key, value in memory.items(): print('adr:{}'.format(key), 'data:{}'.format(value)) raise StopSimulation return stimul, ram, access 

рдЗрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рд░реИрдВрдбрдо рдПрдХреНрд╕реЗрд╕ рдореЛрдб рдореЗрдВ рдЯреЗрд╕реНрдЯ рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рджреВрд╕рд░рд╛ рдЯреЗрд╕реНрдЯрдмреЗрдВрдЪ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ: test_random_access.pyред

рджреВрд╕рд░реЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рд╡рд┐рдЪрд╛рд░ рд╕рдорд╛рди рд╣реИ: рд╣рдо рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдкрддреЗ рдкрд░ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдЬреЛрдбрд╝реЗ {рдкрддрд╛: рдбреЗрдЯрд╛} рдХреЛ temp_mem_write рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдлрд┐рд░ рд╣рдо рдЗрд╕ рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рдкрддреЛрдВ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдореЗрдореЛрд░реА рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдкрдврд╝рддреЗ рд╣реИрдВ, рдЗрд╕реЗ temp_mem_read рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдореБрдЦрд░ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд╕рд╛рде рдЕрдВрдд рдореЗрдВ, рд╣рдо рджреЛ рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред

 import random from myhdl import * from ram_driver import ram_driver @block def testbench_random_access(): data_memory = TristateSignal(intbv(0)[8:]) data_in = Signal(intbv(0)[8:]) data_out = Signal(intbv(0)[8:]) adr = Signal(intbv(0)[16:]) adr_start = Signal(intbv(20)[16:]) adr_write = Signal(bool(0)) read, write, we = [Signal(bool(1)) for i in range(3)] ram = ram_driver(data_in, data_out, adr, adr_start, adr_write, data_memory, read, write, we) memory ={i:intbv(0) for i in range(128)} mem_z = data_memory.driver() @always_comb def access(): if not we: memory[int(adr.val)] = data_memory.val if we: data_out.next = memory[int(adr.val)] mem_z.next = None @instance def stimul(): for time in range(10): temp_mem_write = {} temp_mem_read = {} yield delay(100) for i in range(64): write.next = 1 adr_write.next = 1 adr_start.next = random.randint(0, 126) yield delay(100) adr_write.next = 0 yield delay(100) write.next = 0 data_in.next = random.randint(0, 100) temp_mem_write[int(adr_start.val)] = int(data_in.next) yield delay(100) write.next = 1 yield delay(100) for key in temp_mem_write.keys(): adr_start.next = key adr_write.next = 1 yield delay(100) adr_write.next = 0 yield delay(100) read.next = 0 temp_mem_read[key] = int(data_out.val) yield delay(100) read.next = 1 yield delay(100) assert temp_mem_write == temp_mem_read, '  random access' raise StopSimulation return stimul, ram, access tb = testbench_random_access() tb.config_sim(trace=True) tb.run_sim() 

рдкрд╛рдпрдерди рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рд░реВрдкрд░реЗрдЦрд╛рдПрдВ рд╣реИрдВред рдореИрдВ рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП рдкреВрд░реА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛, рдЗрд╕реЗ рдкрд╛рдЗрдк рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:

 pip3 install pytest 

рдЬрдм рдХрдВрд╕реЛрд▓ рд╕реЗ "pysest" рдХрдорд╛рдВрдб рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдлреНрд░реЗрдорд╡рд░реНрдХ рдЙрдирдХреЗ рдирд╛рдо рдореЗрдВ "test_ *" рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рднреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдвреВрдВрдв рдФрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛ред



рдЯреЗрд╕реНрдЯ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕рдВрдкрдиреНрди рд╣реБрдПред рдореИрдВ рдЙрдкрдХрд░рдг рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЧрд▓рддреА рдХрд░реВрдВрдЧрд╛:

 @block def ram_driver(data_in, data_out, adr, adr_start, adr_write, data_memory, read, write, we): mem_z = data_memory.driver() @always(adr_write.posedge, write.posedge, read.negedge) def write_start_adr(): if adr_write: adr.next = adr_start else: adr.next = adr + 1 @always(write) def write_data(): if not write: mem_z.next = data_in we.next = 1 #  ,    else: mem_z.next = None data_out.next = data_memory we.next = 1 

рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддрд╛ рд╣реВрдВ:



рдЬреИрд╕рд╛ рдХрд┐ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛, рджреЛрдиреЛрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА (рд╢реВрдиреНрдп) рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЕрд░реНрдерд╛рдд рдирдИ рдЬрд╛рдирдХрд╛рд░реА рджрд░реНрдЬ рдирд╣реАрдВ рдХреА рдЧрдИ рдереАред

рдирд┐рд╖реНрдХрд░реНрд╖


MyHDL рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░ рдЕрдЬрдЧрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЖрдк FPGAs рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд╕рд┐рдд рдлрд░реНрдорд╡реЗрдпрд░ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдЬрдЧрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреА рд╕рдореГрджреНрдз рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рдЧрднрдЧ рдХрд┐рд╕реА рднреА рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд▓реЗрдЦ рдорд╛рдирддрд╛ рд╣реИ:

  • рдПрдХ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдирд╛ рдЬреЛ рдореЗрдореЛрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ;
  • рдореЗрдореЛрд░реА рдореЙрдбрд▓ рдмрдирд╛рдирд╛;
  • рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдХрд╛ рдирд┐рд░реНрдорд╛рдг;
  • pytest рдврд╛рдВрдЪреЗ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рд╕реНрд╡рдЪрд╛рд▓рдиред

Source: https://habr.com/ru/post/hi442010/


All Articles